////////////////////////////////////////////////////////////////////////////////
//                      (c) Intelliquip, Inc. 2001
////////////////////////////////////////////////////////////////////////////////
// $Log:
//  496  Version 10.0 (Current View)1.495       8/1/2011 4:26:12 PM    Hai
//       Hoang       IDD#1757: saveAs back-end code sharing and cleanup
//  495  Version 10.0 (Current View)1.494       8/1/2011 10:35:03 AM   Stephen
//       Kish    IDD#09523:  Updating the send email page for multiple
//       recipients, editable body, and auto pump size in the subject
//  494  Version 10.0 (Current View)1.493       7/28/2011 2:48:26 PM   Stephen
//       Kish    IDD#1757: Sharing saveAs code
//  493  Version 10.0 (Current View)1.492       7/15/2011 12:02:51 PM  Hai
//       Hoang       IDD#1757: added saveAs functionality
//  492  Version 10.0 (Current View)1.491       7/6/2011 10:44:12 AM   Jeff
//       Heigl      IDD#08924: adding Fld_Application to Selector
//  491  Version 10.0 (Current View)1.490       6/27/2011 11:48:14 AM  Stephen
//       Kish    IDD#10000: Fixing sorting on search results page
//  490  Version 10.0 (Current View)1.489       6/1/2011 2:03:52 PM    Scott
//       Frees     IDD 09911:  xSheets and IQX integration
//  489  Version 10.0 (Current View)1.488       6/1/2011 9:56:01 AM    Stephen
//       Kish    IDD#09523: Adding page to send an email of the performance
//       datasheet
//  488  Version 10.0 (Current View)1.487       5/19/2011 2:24:04 PM   Jeff
//       Heigl      IDD#09827: refactoring to template method pattern
//  487  Version 10.0 (Current View)1.486       5/19/2011 11:06:33 AM  Jeff
//       Heigl      IDD#09827: refactoring to move redirect config code out of
//       navigation flags
//  486  Version 10.0 (Current View)1.485       5/19/2011 10:19:07 AM  Jeff
//       Heigl      IDD#09827: removing roundtrip to RedirectConfig servlet 
//  485  Version 10.0 (Current View)1.484       5/16/2011 6:02:51 PM   Eric
//       Zhang      IDD#09837: context menu javascript cleanup
//  484  Version 10.0 (Current View)1.483       5/16/2011 11:36:36 AM  Jeff
//       Heigl      IDD#09827: eliminate redirect to breakoutOfFrames.jsp
//  483  Version 10.0 (Current View)1.482       5/10/2011 11:55:46 AM  Jeff
//       Heigl      IDD#09827: Selector to Configurator latency optimization
//  482  Version 10.0 (Current View)1.481       5/9/2011 12:23:44 PM   Jeff
//       Heigl      IDD#09485: Selector - size list frequency dropdown does not
//       persist
//  481  Version 10.0 (Current View)1.480       5/4/2011 11:02:49 AM   Jeff
//       Heigl      IDD#09523: refactoring cos mobile xsl
//  480  Version 10.0 (Current View)1.479       5/3/2011 2:22:05 PM    Eric
//       Zhang      IDD#09523: Mobile Selector App
//  479  Version 10.0 (Current View)1.478       4/18/2011 10:00:55 AM  Hai
//       Hoang       IDD#09744: yAxis settings decimal separator support
//  478  Version 10.0 (Current View)1.477       4/12/2011 4:11:32 PM   Eric
//       Zhang      IDD#09713: Thumbnails curve page navbar button bugs
//  477  Version 10.0 (Current View)1.476       4/11/2011 1:31:36 PM   Eric
//       Zhang      IDD#09687: Context menu bug
//  476  Version 10.0 (Current View)1.475       3/7/2011 3:32:12 PM    Jeff
//       Heigl      IDD#09452: multiple conditions speed criteria
//  475  Version 10.0 (Current View)1.474       2/28/2011 9:49:49 AM   Stephen
//       Kish    IDD#09403: Bug fixes for enhanced documents page
//  474  Version 10.0 (Current View)1.473       2/24/2011 4:25:49 PM   Eric
//       Zhang      IDD#09036:Hide selection status on all PDF's when user
//       requested
//  473  Version 10.0 (Current View)1.472       2/16/2011 5:43:13 PM   Eric
//       Zhang      IDD#09373: Selector - KE driven alerts at the performance
//       datasheet
//  472  Version 10.0 (Current View)1.471       2/14/2011 11:18:31 AM  Stephen
//       Kish    IDD#08949: Variable clean up
//  471  Version 10.0 (Current View)1.470       2/11/2011 12:18:01 PM  Hai
//       Hoang       IDD#8858: support Bagasse and Stock Correction Factors for
//       KBL
//  470  Version 10.0 (Current View)1.469       2/4/2011 4:31:04 PM    Eric
//       Zhang      IDD#9036:  Hide near miss on pdfs
//  469  Version 10.0 (Current View)1.468       1/24/2011 3:26:34 PM   Stephen
//       Kish    IDD#7855: Moving pages to the abstract design
//  468  Version 10.0 (Current View)1.467       1/6/2011 5:33:06 PM    Hai
//       Hoang       IDD#08921: Curve's yAxis override
//  467  Version 10.0 (Current View)1.466       12/16/2010 9:47:33 AM  Stephen
//       Kish    IDD#7855: Moving pages to Abstract selector page design.
//  466  Version 10.0 (Current View)1.465       12/13/2010 10:25:31 AM Hai
//       Hoang       IDD#08953, 8227, 09236: npsha, liquid properties, and
//       driverRating popup fixes.
//  465  Version 10.0 (Current View)1.464       12/9/2010 4:48:42 PM   Stephen
//       Kish    IDD#7885: Migrating pages to Abstract Selector Page design
//  464  Version 10.0 (Current View)1.463       12/8/2010 10:23:03 AM  Stephen
//       Kish    IDD#7885: Migrating pages to abstract selector design.
//  463  Version 10.0 (Current View)1.462       12/6/2010 3:34:24 PM   Hai
//       Hoang       IDD#08973: lccAnnualEnergyCost added to searchResults page
//  462  Version 10.0 (Current View)1.461       12/6/2010 12:26:03 PM  Stephen
//       Kish    IDD#7885: Moving selector pages to Abstract selector page
//       design
//  461  Version 10.0 (Current View)1.460       12/2/2010 9:08:56 AM   Stephen
//       Kish    IDD#7885: Migrating pages to abstract selector design.
//  460  Version 10.0 (Current View)1.459       12/1/2010 9:46:26 AM   Jeff
//       Heigl      IDD#09314: fixed curve label reset bug, compare mode bug
//  459  Version 10.0 (Current View)1.458       11/11/2010 2:57:37 PM  Hai
//       Hoang       IDD#08973:  display annualEnergyCost on searchResults page
//  458  Version 10.0 (Current View)1.457       11/11/2010 11:52:44 AM Stephen
//       Kish    IDD#7885: Migrating selector pages to Abstract design
//  457  Version 10.0 (Current View)1.456       11/9/2010 9:31:14 AM   Stephen
//       Kish    IDD#7885:  Migrating pages to use Abstract Selector design
//  456  Version 10.0 (Current View)1.455       11/5/2010 1:05:25 PM   Stephen
//       Kish    IDD#6245: Refactoring changes
//  455  Version 10.0 (Current View)1.454       11/4/2010 10:49:01 AM  Stephen
//       Kish    IDD#7885: Modified selector pages to use abstract selector
//       page design.
//  454  Version 10.0 (Current View)1.453       10/27/2010 9:47:27 AM  Durga
//       Brahmandam IDD#0920:serverRoot parameter removed from soap calls.
//  453  Version 10.0 (Current View)1.452       10/19/2010 2:26:24 PM  Stephen
//       Kish    IDD#6245: Refactoring HttpSessions.get and set Attribute to
//       use DAO classes
//  452  Version 10.0 (Current View)1.451       10/7/2010 4:52:03 PM   Jeff
//       Heigl      IDD#9126: new item servlet cleanup
//  451  Version 10.0 (Current View)1.450       9/28/2010 3:37:08 PM   Jeff
//       Heigl      IDD#09109: setting speed user to 0 from the search page
//       when motor curves are not enabled
//  450  Version 10.0 (Current View)1.449       8/25/2010 5:25:44 PM   Eric
//       Zhang      IDD#8969: Curve color preferences
//  449  Version 10.0 (Current View)1.448       8/6/2010 11:10:19 AM   Eric
//       Zhang      IDD#8944: Selector search result context menu
//  448  Version 10.0 (Current View)1.447       8/3/2010 3:58:29 PM    Stephen
//       Kish    IDD#8949: Refactoring appRootFile and getServerRoot
//  447  Version 10.0 (Current View)1.446       7/27/2010 9:36:04 AM   Hai
//       Hoang       IDD#8955: Use label for QMConfig field that doesn't exist
//  446  Version 10.0 (Current View)1.445       7/20/2010 4:09:52 PM   Eric
//       Zhang      IDD#8951: Twistie Settings Persistance Problems
//  445  Version 10.0 (Current View)1.444       7/19/2010 5:21:22 PM   Hai
//       Hoang       IDD#8227: clean up liquidProperties page
//  444  Version 10.0 (Current View)1.443       7/9/2010 4:33:21 PM    Hai
//       Hoang       IDD#7072: phase 1 of air operated diaphragm pump
//  443  Version 10.0 (Current View)1.442       6/21/2010 3:21:31 PM   Durga
//       Brahmandam IDD#7868:  Item save from Navbar buttons.
//  442  Version 10.0 (Current View)1.441       6/1/2010 5:44:09 PM    Jeff
//       Heigl      IDD#8601: Turbocompressor connection to Configurator for
//       ABS
//  441  Version 10.0 (Current View)1.440       5/28/2010 10:10:01 AM  Hai
//       Hoang       IDD#8824: added dirty flag to ITO cos page
//  440  Version 10.0 (Current View)1.439       5/28/2010 9:16:32 AM   Hai
//       Hoang       IDD#8821: fixed searchResult cache problem
//  439  Version 10.0 (Current View)1.438       4/15/2010 5:53:08 PM   Hai
//       Hoang       IDD#7880: check for density and viscosity > 0.0
//  438  Version 10.0 (Current View)1.437       4/14/2010 4:09:52 PM   Hai
//       Hoang       IDD#8155: fixed problem with decimal separator
//  437  Version 10.0 (Current View)1.436       4/1/2010 11:21:56 AM   Jeff
//       Heigl      IDD#8144: hide near misses for compressor datasheet
//  436  Version 10.0 (Current View)1.435       3/18/2010 3:19:39 PM   Jeff
//       Heigl      IDD#8431: variable speed power data table - UI and
//       persistence
//  435  Version 10.0 (Current View)1.434       3/18/2010 2:14:28 PM   Hai
//       Hoang       IDD#8420: High Speed MultiStage Selections 
//  434  Version 10.0 (Current View)1.433       2/24/2010 10:33:07 AM  Jeff
//       Heigl      IDD#8431: compressor pdf infrastructure
//  433  Version 10.0 (Current View)1.432       2/16/2010 10:37:56 AM  Eric
//       Zhang      IDD#7859: Hide near miss on PDF
//  432  Version 10.0 (Current View)1.431       2/12/2010 3:31:39 PM   Eric
//       Zhang      IDD#7859: Hide near miss on pdf
//  431  Version 10.0 (Current View)1.430       1/20/2010 11:25:03 AM  Jeff
//       Heigl      IDD#8270: compressor to support new item with preselected
//       productline 
//  430  Version 10.0 (Current View)1.429       1/13/2010 5:00:37 PM   Jeff
//       Heigl      IDD#8270: ensure performance option defaults are
//       initialized before they are used
//  429  Version 10.0 (Current View)1.428       1/13/2010 4:25:53 PM   Jeff
//       Heigl      IDD#8270: compressor power limit subcats displayed and
//       persisted on cos page
//  428  Version 10.0 (Current View)1.427       1/12/2010 9:36:22 AM   Jeff
//       Heigl      IDD#8270: refactoring prod options xml code, bug fix for
//       driver sizing spec subcat logic
//  427  Version 10.0 (Current View)1.426       1/11/2010 2:54:11 PM   Jeff
//       Heigl      IDD#8270: productline options for compressors, refactoring
//  426  Version 10.0 (Current View)1.425       1/11/2010 10:27:19 AM  Jeff
//       Heigl      IDD#8270: productline options stored in compressor cos
//  425  Version 10.0 (Current View)1.424       1/7/2010 4:00:23 PM    Jeff
//       Heigl      IDD#8270: refactoring - rename methods
//  424  Version 10.0 (Current View)1.423       1/6/2010 2:34:15 PM    Jeff
//       Heigl      IDD#8270: refactoring ProductOptionsFactory dependencies
//  423  Version 10.0 (Current View)1.422       1/5/2010 3:33:07 PM    Jeff
//       Heigl      IDD#8270: performance options storage refactoring
//  422  Version 10.0 (Current View)1.421       11/16/2009 5:27:19 PM  Eric
//       Zhang      IDD#8193: Compressor page update
//  421  Version 10.0 (Current View)1.420       11/11/2009 4:06:01 PM  Jeff
//       Heigl      IDD#8193: compare mode can have a result from 2 different
//       productlines
//  420  Version 10.0 (Current View)1.419       11/11/2009 12:04:08 PM Hai
//       Hoang       IDD#8235: Units of Measure Reconciliation for
//       Intellisheets and IFE, unitOfMeasure.xml cleanup
//  419  Version 10.0 (Current View)1.418       11/2/2009 9:37:28 AM   Jeff
//       Heigl      IDD#8193: Fixed gas constituents popup persistence issues
//       with cancel button.  Fixed selected gasses are not persisted with a
//       saved item.
//  418  Version 10.0 (Current View)1.417       10/30/2009 10:04:18 AM Jeff
//       Heigl      IDD#8193: toggle all now applied to new selections
//  417  Version 10.0 (Current View)1.416       10/21/2009 2:15:53 PM  Jeff
//       Heigl      IDD#8193: gas constituents dropdown support.  Allow unit
//       tests to reset the selectorContext
//  416  Version 10.0 (Current View)1.415       10/20/2009 10:07:09 AM Jeff
//       Heigl      IDD#8193: gas constituents page impl
//  415  Version 10.0 (Current View)1.414       10/19/2009 5:52:45 PM  Jeff
//       Heigl      IDD#8193: gas constituents normalize button
//  414  Version 10.0 (Current View)1.413       10/14/2009 4:26:45 PM  Jeff
//       Heigl      IDD#8193: refactoring to support gas constituents page
//       submit
//  413  Version 10.0 (Current View)1.412       10/14/2009 3:10:24 PM  Jeff
//       Heigl      IDD#8193: infrastructure for gas constituents popup page
//  412  Version 10.0 (Current View)1.411       10/13/2009 11:59:50 AM Jeff
//       Heigl      IDD#8193: compressor header info persistence and cleanup
//  411  Version 10.0 (Current View)1.410       10/12/2009 3:56:59 PM  Jeff
//       Heigl      IDD#8193: reset for new selection
//  410  Version 10.0 (Current View)1.409       10/7/2009 12:29:13 PM  Jeff
//       Heigl      IDD#8179: size list UI and backend tied together
//  409  Version 10.0 (Current View)1.408       10/7/2009 10:41:26 AM  Jeff
//       Heigl      IDD#8179: size list selection search
//  408  Version 10.0 (Current View)1.407       10/6/2009 12:14:03 PM  Jeff
//       Heigl      IDD#8179: selection from size list infrastructure
//  407  Version 10.0 (Current View)1.406       10/5/2009 11:47:59 AM  Jeff
//       Heigl      IDD#8083: product lines next button, start page home origin
//  406  Version 10.0 (Current View)1.405       10/2/2009 2:52:35 PM   Jeff
//       Heigl      IDD#8179: compressor size list page xml
//  405  Version 10.0 (Current View)1.404       9/29/2009 1:09:28 PM   Jeff
//       Heigl      IDD#8109: infrastructure for selections
//  404  Version 10.0 (Current View)1.403       9/24/2009 10:33:27 AM  Jeff
//       Heigl      IDD#8031: fixed compressor save, scroll y submit logic
//       cleanup
//  403  Version 10.0 (Current View)1.402       9/21/2009 11:19:36 AM  Jeff
//       Heigl      IDD#8144: parallel models now editable on datasheet
//  402  Version 10.0 (Current View)1.401       9/17/2009 11:02:38 AM  Eric
//       Zhang      IDD#8122: Compressor startpage javascript
//  401  Version 10.0 (Current View)1.400       9/17/2009 11:01:40 AM  Eric
//       Zhang      IDD#7990: Selector page refresh position persistence
//  400  Version 10.0 (Current View)1.399       9/9/2009 9:36:15 AM    Hai
//       Hoang       IDD#8104: remove pumpDetails when selected productline is
//       changed
//  399  Version 10.0 (Current View)1.398       9/8/2009 12:24:43 PM   Jeff
//       Heigl      IDD#8031: compressor sort plugged into the UI
//  398  Version 10.0 (Current View)1.397       9/1/2009 4:15:19 PM    Jeff
//       Heigl      IDD#8083: userPreferences flag cleanup, navigation logic
//       bug fixes
//  397  Version 10.0 (Current View)1.396       8/25/2009 10:38:52 AM  Jeff
//       Heigl      IDD#8031: selected search results persistence
//  396  Version 10.0 (Current View)1.395       8/24/2009 4:02:40 PM   Jeff
//       Heigl      IDD#8031: multipleCos and primaryCos datasheet modes
//       supported and tested
//  395  Version 10.0 (Current View)1.394       8/24/2009 2:33:29 PM   Jeff
//       Heigl      IDD#8031: search results links implemented
//  394  Version 10.0 (Current View)1.393       8/21/2009 2:54:05 PM   Jeff
//       Heigl      IDD#8031: selected models and result caching
//  393  Version 10.0 (Current View)1.392       8/18/2009 4:42:22 PM   Eric
//       Zhang      IDD#7911: Compressor COS persistence and tab order
//  392  Version 10.0 (Current View)1.391       8/13/2009 1:44:01 PM   Jeff
//       Heigl      IDD#8031: compressor search inputs
//  391  Version 10.0 (Current View)1.390       8/4/2009 10:14:32 AM   Eric
//       Zhang      IDD#8046: Pump life filed input separator problem
//  390  Version 10.0 (Current View)1.389       7/23/2009 9:28:28 AM   Jeff
//       Heigl      IDD#8031: compressor datasheet page, code cleanup
//  389  Version 10.0 (Current View)1.388       7/21/2009 5:40:46 PM   Hai
//       Hoang       IDD#7250: Mongoose integration
//  388  Version 10.0 (Current View)1.387       7/21/2009 4:24:46 PM   Jeff
//       Heigl      IDD#7911: setup compressor search page, code cleanup
//  387  Version 10.0 (Current View)1.386       7/20/2009 12:26:33 PM  Jeff
//       Heigl      IDD#7911: page submit refactoring, comment cleanup
//  386  Version 10.0 (Current View)1.385       7/15/2009 3:26:18 PM   Jeff
//       Heigl      IDD#7911: copy from button working
//  385  Version 10.0 (Current View)1.384       7/13/2009 9:19:23 AM   Jeff
//       Heigl      IDD#7911: compressor cos recalc button working
//  384  Version 10.0 (Current View)1.383       7/8/2009 9:46:59 AM    Jeff
//       Heigl      IDD#7911: compressor calculation changes for average
//       temperature
//  383  Version 10.0 (Current View)1.382       6/25/2009 3:46:10 PM   Hai
//       Hoang       IDD#7965: fixed lastModified date for items already saved
//  382  Version 10.0 (Current View)1.381       5/22/2009 3:34:44 PM   Eric
//       Zhang      IDD#7880: viscosity input value causing crash on
//       performance ds page
//  381  Version 10.0 (Current View)1.380       5/7/2009 3:04:27 PM    Eric
//       Zhang      IDD#7676: Fixed empty row on PD perfDatasheet page and
//       fixed page refresh persistance problem on some other pages
//  380  Version 10.0 (Current View)1.379       4/6/2009 2:10:42 PM    Hai
//       Hoang       IDD#7701: fixed invalid navbar submit problem
//  379  Version 10.0 (Current View)1.378       3/23/2009 2:51:40 PM   Eric
//       Zhang      IDD#6948: scroll persistance
//  378  Version 10.0 (Current View)1.377       3/19/2009 10:03:30 AM  Eric
//       Zhang      IDD#7383: multiple conditions issues
//  377  Version 10.0 (Current View)1.376       3/10/2009 2:24:54 PM   Jeff
//       Heigl      IDD#7584: multi conditions now supporting variable speed
//       for all pumps
//  376  Version 10.0 (Current View)1.375       2/11/2009 5:53:21 PM   Hai
//       Hoang       IDD#7518: fixed Liquid Type pop up doesn't refresh search
//       results
//  375  Version 10.0 (Current View)1.374       2/6/2009 6:04:06 PM    Hai
//       Hoang       IDD#7493: fixed SelectionBody doesn't auto submit when
//       click preferences link
//  374  Version 10.0 (Current View)1.373       1/14/2009 11:04:55 AM  Jeff
//       Heigl      IDD#7024: sel config now passed into search, search
//       parameters object created
//  373  Version 10.0 (Current View)1.372       1/6/2009 3:41:34 PM    Eric
//       Zhang      IDD#7383: multiple conditions page bugs
//  372  Version 10.0 (Current View)1.371       1/5/2009 3:31:12 PM    Jeff
//       Heigl      IDD#7383: fluid density adjustment for multiple conditions,
//       npsh ample bugs
//  371  Version 10.0 (Current View)1.370       12/12/2008 3:33:22 PM  Eric
//       Zhang      IDD#7307: Selector quote xml implementation
//  370  Version 10.0 (Current View)1.369       12/12/2008 10:27:57 AM Jeff
//       Heigl      IDD#7282: implementing system fields for search
//  369  Version 10.0 (Current View)1.368       12/10/2008 11:57:30 AM Jeff
//       Heigl      IDD#7283: implementing the remaining curve prefs on the UI
//  368  Version 10.0 (Current View)1.367       12/9/2008 3:59:37 PM   Jeff
//       Heigl      IDD#7283: implementing http submit logic
//  367  Version 10.0 (Current View)1.366       12/8/2008 4:27:01 PM   Jeff
//       Heigl      IDD#7280: impl ito actual head, eta and bug fixes for
//       search result recalc
//  366  Version 10.0 (Current View)1.365       12/1/2008 9:56:48 AM   Jeff
//       Heigl      IDD#7282: multiple conditions speed set implemented
//  365  Version 10.0 (Current View)1.364       11/24/2008 2:05:11 PM  Jeff
//       Heigl      IDD#7280: speed rated and checkbox for multiple conditions
//  364  Version 10.0 (Current View)1.363       11/21/2008 3:50:57 PM  Jeff
//       Heigl      IDD#7280: multiple conditions page now allows change
//       primary condition
//  363  Version 10.0 (Current View)1.362       11/20/2008 4:05:02 PM  Hai
//       Hoang       IDD#7256: gen and save specific Selector pdf over SOAP
//  362  Version 10.0 (Current View)1.361       11/13/2008 2:49:44 PM  Jeff
//       Heigl      IDD#7283: multiple condition persistence refactoring
//  361  Version 10.0 (Current View)1.360       11/6/2008 2:15:52 PM   Jeff
//       Heigl      IDD#7283: mutliple conditions pages fully support head and
//       flow
//  360  Version 10.0 (Current View)1.359       10/31/2008 10:46:36 AM Jeff
//       Heigl      IDD#7283: refactoring multiple conditions xml to have index
//       as an attribute
//  359  Version 10.0 (Current View)1.358       10/30/2008 4:54:15 PM  Jeff
//       Heigl      IDD#7283: multiple conditions persistence infrastructure in
//       place
//  358  Version 10.0 (Current View)1.357       10/28/2008 3:01:21 PM  Hai
//       Hoang       IDD#7279: Multiple conditions page GUI infrastructure
//  357  Version 10.0 (Current View)1.356       10/28/2008 9:54:38 AM  Jeff
//       Heigl      IDD#7283: refactoring old multiple conditions code
//  356  Version 10.0 (Current View)1.355       10/23/2008 6:15:07 PM  Hai
//       Hoang       IDD#7273: speed, rated filed fix for speed solvevariant
//  355  Version 10.0 (Current View)1.354       10/15/2008 10:53:02 AM Hai
//       Hoang       IDD#6273: api610 10th edition support
//  354  Version 10.0 (Current View)1.353       10/13/2008 11:59:47 AM Jeff
//       Heigl      IDD#6092: code reuse refactoring
//  353  Version 10.0 (Current View)1.352       9/29/2008 3:09:59 PM   Hai
//       Hoang       IDD#7132: persisting userSettings across all apps
//  352  Version 10.0 (Current View)1.351       8/25/2008 9:27:30 AM   Jeff
//       Heigl      IDD#7047: user curve comment message
//  351  Version 10.0 (Current View)1.350       8/22/2008 10:36:00 AM  Jeff
//       Heigl      IDD#7047: bug fixes for performance adjustment
//  350  Version 10.0 (Current View)1.349       8/12/2008 3:41:02 PM   Eric
//       Zhang      IDD#7047: User defined performance adjustment factor
//  349  Version 10.0 (Current View)1.348       8/5/2008 10:02:38 AM   Eric
//       Zhang      IDD#7064:Change to not recalculate and submit page when
//       open logs
//  348  Version 10.0 (Current View)1.347       7/24/2008 4:27:23 PM   Hai
//       Hoang       IDD#6338: catalogTrimsSelectionMode implemented
//  347  Version 10.0 (Current View)1.346       6/27/2008 2:37:41 PM   Eric
//       Zhang      IDD#6454: Clean up prodTitle usage inconsistency
//  346  Version 10.0 (Current View)1.345       6/23/2008 3:14:07 PM   Jeff
//       Heigl      IDD#6867: refactoring - moving classes, pt4
//  345  Version 10.0 (Current View)1.344       6/23/2008 12:10:43 PM  Jeff
//       Heigl      IDD#6867: refactoring - moving classes, pt3
//  344  Version 10.0 (Current View)1.343       6/4/2008 9:53:45 AM    Eric
//       Zhang      IDD#6949: Change NavBar into twistie which shows/hides upon
//       user's choice, and remove hideNavBar button at Condition Of Service
//       page
//  343  Version 10.0 (Current View)1.342       5/21/2008 7:18:23 AM   Durga
//       Brahmandam IDD#6901:Selector - formatting numbers based on currency
//  342  Version 10.0 (Current View)1.341       4/16/2008 10:51:25 AM  Jeff
//       Heigl      IDD#6860: KSB systemCurve flow and head bug
//  341  Version 10.0 (Current View)1.340       3/19/2008 11:14:26 AM  Hai
//       Hoang       IDD#6690: LCC - Decimal grouping/Decimal Symbol
//  340  Version 10.0 (Current View)1.339       3/12/2008 1:45:35 PM   Durga
//       Brahmandam IDD#6686:IQ Solutions - Troubleshooting issues.
//       SelectorProperties.xml display support in Admin menu.
//  339  Version 10.0 (Current View)1.338       3/7/2008 6:09:42 PM    Jeff
//       Heigl      IDD#6592: Persist the state of the twisties on the head
//       loss page (inline or none). 
//  338  Version 10.0 (Current View)1.337       3/7/2008 4:29:01 PM    Jeff
//       Heigl      IDD#6592: head loss recalc scrolls to the same position
//  337  Version 10.0 (Current View)1.336       2/28/2008 5:48:31 PM   Hai
//       Hoang       IDD#6260: custom ns and nss UOM
//  336  Version 10.0 (Current View)1.335       2/21/2008 4:39:30 PM   Hai
//       Hoang       IDD#6636: reject from changing liquidType with certain
//       UOMs
//  335  Version 10.0 (Current View)1.334       2/21/2008 2:18:26 PM   Jeff
//       Heigl      IDD#6592: head loss flow now updates the system curve only
//  334  Version 10.0 (Current View)1.333       2/20/2008 4:44:08 PM   Jeff
//       Heigl      IDD#6623: adding comments
//  333  Version 10.0 (Current View)1.332       2/20/2008 4:18:40 PM   Jeff
//       Heigl      IDD#6623: code cleanup related to fluid density adjustments
//  332  Version 10.0 (Current View)1.331       2/18/2008 5:21:28 PM   Hai
//       Hoang       IDD#6531: fixed conversion involving fluidDensity
//  331  Version 10.0 (Current View)1.330       2/12/2008 9:57:24 AM   Eric
//       Zhang      IDD#6427: add enable/unable attribute check on lcc page,
//       define strategy to create new profile when user enters flow =0
//  330  Version 10.0 (Current View)1.329       2/8/2008 3:09:23 PM    Hai
//       Hoang       IDD#6033: HI-2004 viscosityCorrection spec implemented
//  329  Version 10.0 (Current View)1.328       2/8/2008 2:28:30 PM    Jeff
//       Heigl      IDD#6580: fitting data loss warning
//  328  Version 10.0 (Current View)1.327       2/8/2008 10:28:45 AM   Jeff
//       Heigl      IDD#6580: the nom pipe size units is now independent for
//       each head loss system number
//  327  Version 10.0 (Current View)1.326       2/7/2008 4:28:57 PM    Jeff
//       Heigl      IDD#6580: head loss - Nominal Pipe Size Units variable
//       introduced
//  326  Version 10.0 (Current View)1.325       1/29/2008 2:53:38 PM   Jeff
//       Heigl      IDD#5830: code cleanup - removing the Fitting request
//       (submit) heirarchy
//  325  Version 10.0 (Current View)1.324       1/25/2008 2:47:54 PM   Hai
//       Hoang       IDD#6501: calculated mode for ITO on multispeedcurve page
//  324  Version 10.0 (Current View)1.323       1/24/2008 4:25:17 PM   Jeff
//       Heigl      IDD#5830: organiing imports, using uom conversion factors
//       with head loss conversions
//  323  Version 10.0 (Current View)1.322       1/23/2008 3:49:19 PM   Jeff
//       Heigl      IDD#6526: creating a sample head loss pdf and getting it to
//       work through the UI
//  322  Version 10.0 (Current View)1.321       1/21/2008 9:43:49 AM   Hai
//       Hoang       IDD#6515: fixed ABS strange reject
//  321  Version 10.0 (Current View)1.320       1/18/2008 10:14:03 AM  Jeff
//       Heigl      IDD#5830: head loss InputData uom cleanup
//  320  Version 10.0 (Current View)1.319       1/17/2008 1:58:27 PM   Jeff
//       Heigl      IDD#6514: Support CustomDataServlet within Selector
//  319  Version 10.0 (Current View)1.318       1/16/2008 2:06:05 PM   Jeff
//       Heigl      IDD#5830: Hazen williams viscosity range check implemented
//  318  Version 10.0 (Current View)1.317       1/16/2008 1:42:54 PM   Jeff
//       Heigl      IDD#5830: system curve label and visibility persistence
//       from the head loss page
//  317  Version 10.0 (Current View)1.316       1/15/2008 4:08:10 PM   Jeff
//       Heigl      IDD#5830: reading input data fields from UI submit
//  316  Version 10.0 (Current View)1.315       1/15/2008 3:04:33 PM   Jeff
//       Heigl      IDD#5830: setting head loss calc'd values into operating
//       conditions and system curves
//  315  Version 10.0 (Current View)1.314       12/28/2007 4:59:27 PM  Hai
//       Hoang       IDD#6349: Fixed first stage and mixed stage combined
//  314  Version 10.0 (Current View)1.313       12/27/2007 12:03:00 PM Jeff
//       Heigl      IDD#5830: headLoss now passes the itemXML and quoteXML to
//       the config
//  313  Version 10.0 (Current View)1.312       12/21/2007 10:20:34 AM Jeff
//       Heigl      IDD#6383: kPa.s now uses fluid density to compute its
//       conversion factor
//  312  Version 10.0 (Current View)1.311       12/20/2007 12:48:54 PM Jeff
//       Heigl      IDD#6430: Selector - CurveNumber data element in item.xml
//       inconsistency
//  311  Version 10.0 (Current View)1.310       12/7/2007 2:39:39 PM   Jeff
//       Heigl      IDD#5830: system type UI submit logic added
//  310  Version 10.0 (Current View)1.309       12/5/2007 5:26:07 PM   Jeff
//       Heigl      IDD#5830: fitting selection and special fitting submit
//       cleanup
//  309  Version 10.0 (Current View)1.308       12/4/2007 5:26:20 PM   Hai
//       Hoang       IDD#6362: recalculate functionality
//  308  Version 10.0 (Current View)1.307       12/3/2007 5:50:22 PM   Hai
//       Hoang       IDD#6362:  GUI interactions
//  307  Version 10.0 (Current View)1.306       12/3/2007 3:39:43 PM   Jeff
//       Heigl      IDD#5830: Picklist has been generalized to extract an
//       XmlList
//  306  Version 10.0 (Current View)1.305       12/3/2007 10:38:03 AM  Hai
//       Hoang       IDD#6362: GUI navigations
//  305  Version 10.0 (Current View)1.304       11/26/2007 3:23:54 PM  Jeff
//       Heigl      IDD#5830: move all head loss objects to core so they can be
//       transferred between apps
//  304  Version 10.0 (Current View)1.303       11/21/2007 4:54:11 PM  Jeff
//       Heigl      IDD#5830: adding unit of measure support to the head loss
//       module
//  303  Version 10.0 (Current View)1.302       11/16/2007 4:04:45 PM  Durga
//       Brahmandam IDD#6303: org-setup.xml display support from Logs menu.
//  302  Version 10.0 (Current View)1.301       11/13/2007 4:13:29 PM  Jeff
//       Heigl      IDD#5830: reading more parameters from head loss submit and
//       reorganizing
//  301  Version 10.0 (Current View)1.300       11/13/2007 3:19:18 PM  Jeff
//       Heigl      IDD#5830: implementing fail fast error handling and the
//       HeadLoss copyTo functionality
//  300  Version 10.0 (Current View)1.299       11/13/2007 11:20:51 AM Jeff
//       Heigl      IDD#5830: all update fitting actions are now implemented
//       and under test
//  299  Version 10.0 (Current View)1.298       11/12/2007 1:18:47 PM  Jeff
//       Heigl      IDD#5830: fix method override bug
//  298  Version 10.0 (Current View)1.297       11/12/2007 10:39:35 AM Jeff
//       Heigl      IDD#5830: java backend object pt7.  Update fittings is now
//       fail fast.  Add and Delete fittings are under test.  
//  297  Version 10.0 (Current View)1.296       11/9/2007 1:04:59 PM   Jeff
//       Heigl      IDD#5830: java objects checkin, pt7
//  296  Version 10.0 (Current View)1.295       11/6/2007 5:18:31 PM   Jeff
//       Heigl      IDD#5830: head loss java backend pt5
//  295  Version 10.0 (Current View)1.294       11/5/2007 6:12:32 PM   Jeff
//       Heigl      IDD#5830: head loss java objects, pt5
//  294  Version 10.0 (Current View)1.293       11/5/2007 5:01:37 PM   Jeff
//       Heigl      IDD#5830: head loss java objects, pt4
//  293  Version 10.0 (Current View)1.292       11/5/2007 1:37:00 PM   Jeff
//       Heigl      IDD#5830: java backend objects, pt3
//  292  Version 10.0 (Current View)1.291       11/5/2007 11:33:28 AM  Jeff
//       Heigl      IDD#5830: java backend objects, pt2
//  291  Version 10.0 (Current View)1.290       11/5/2007 8:57:21 AM   Jeff
//       Heigl      IDD#5830: beginning the java object model for the head loss
//       module
//  290  Version 10.0 (Current View)1.289       10/24/2007 5:40:15 PM  Jeff
//       Heigl      IDD#5830: refactoring
//  289  Version 10.0 (Current View)1.288       10/24/2007 4:29:42 PM  Jeff
//       Heigl      IDD#5830: UI structuring to support the head loss popup
//       windows
//  288  Version 10.0 (Current View)1.287       10/23/2007 5:26:30 PM  Jeff
//       Heigl      IDD#5830: UI structuring and prep for head loss module
//  287  Version 10.0 (Current View)1.286       10/22/2007 9:22:11 AM  Jeff
//       Heigl      IDD#5830: UI structuring for head loss page
//  286  Version 10.0 (Current View)1.285       7/10/2007 11:13:06 AM  Jeff
//       Heigl      IDD#6014: LifeCycleCst energyCost not using proper
//       separators and formatting
//  285  Version 10.0 (Current View)1.284       6/27/2007 4:00:42 PM   Jeff
//       Heigl      IDD#5961: Selector - Error at multispeed curve page
//  284  Version 10.0 (Current View)1.283       6/8/2007 10:25:38 AM   Scott
//       Frees     IDD #5880:  Fixed AFS problems when recalculating
//  283  Version 10.0 (Current View)1.282       5/18/2007 4:11:46 PM   Scott
//       Frees     IDD #5793:  Removed unnecessary object instantiations
//  282  Version 10.0 (Current View)1.281       5/8/2007 1:49:48 PM    Jeff
//       Heigl      IDD#5426: Selector - Completion of Minimize trimmed stages
//       (using HPM.CYBI)
//  281  Version 10.0 (Current View)1.280       3/20/2007 10:25:05 AM  Durga
//       Brahmandam IDD#5639: while saving an item (quick or complete save) all
//       item docs are first deleted from db. 
//  280  Version 10.0 (Current View)1.279       3/13/2007 4:09:47 PM   Durga
//       Brahmandam IDD#5624: saveItem() method signature enhancements made:
//       boolean hasItemDocs param added. For 'quickSave' the param value will
//       be passed in as 'false'.
//  279  Version 10.0 (Current View)1.278       2/12/2007 10:56:55 AM  Jeff
//       Heigl      IDD#5565: Selector - ITO search vs. thumbnails
//  278  Version 10.0 (Current View)1.277       1/2/2007 5:12:31 PM    Vishnu
//       Akkaraju customer and quote integration
//  277  Version 10.0 (Current View)1.276       12/19/2006 4:33:45 PM  Hai
//       Hoang       IDD#4920: clear the "set @" checkboxes when reselecting a
//       pump from the size list or search results.
//  276  Version 10.0 (Current View)1.275       10/17/2006 11:49:10 AM Hai
//       Hoang       IDD#4920: Selector - Minimize trimmed stages enhancements
//  275  Version 10.0 (Current View)1.274       9/27/2006 2:45:38 PM   Vishnu
//       Akkaraju idd #5276 -- date formatter problems
//  274  Version 10.0 (Current View)1.273       9/14/2006 4:10:50 PM   Hai
//       Hoang       IDD#5139: -added user's custom date format
//  273  Version 10.0 (Current View)1.272       9/8/2006 4:18:14 PM    Vishnu
//       Akkaraju idd #4860 -- Save and return to QM to logout from HydSel
//       fixed
//  272  Version 10.0 (Current View)1.271       8/18/2006 4:30:15 PM   Jeff
//       Heigl      IDD#4787: old language code removed
//  271  Version 10.0 (Current View)1.270       8/7/2006 10:35:35 AM   Hai
//       Hoang       IDD#4920: -Minimize trimmed stages enhancements
//  270  Version 10.0 (Current View)1.269       7/25/2006 10:03:28 AM  Jeff
//       Heigl      IDD#4995: QM rewrite for workflow
//  269  Version 10.0 (Current View)1.268       7/12/2006 2:40:53 PM   Jeff
//       Heigl      IDD#4977: bug fixes related to motor speed enhancements
//  268  Version 10.0 (Current View)1.267       7/11/2006 11:08:00 AM  Hai
//       Hoang       IDD#5093: -Eliminate eclipse warnings
//  267  Version 10.0 (Current View)1.266       6/26/2006 5:29:44 PM   Hai
//       Hoang       IDD#4977: -fixed menu on motorperformance page
//  266  Version 10.0 (Current View)1.265       6/22/2006 9:40:17 AM   Hai
//       Hoang       IDD#4977: -data added to motorPerf UI
//  265  Version 10.0 (Current View)1.264       6/20/2006 9:58:05 AM   Hai
//       Hoang       IDD#5038: -changing the liquip type or max temp on the
//       liquid properties page now regenerates the search result.
//  264  Version 10.0 (Current View)1.263       6/7/2006 12:20:59 PM   Hai
//       Hoang       IDD#4977: Selector - ABS - Motor speed logic
//       -added phase and driver design display logic
//  263  Version 10.0 (Current View)1.262       5/31/2006 11:19:11 AM  Jeff
//       Heigl      IDD#5019: incompatible productLine auto-pick causing
//       problems
//  262  Version 10.0 (Current View)1.261       5/30/2006 11:55:58 AM  Jeff
//       Heigl      IDD#5010: Selector - Flow #2 setting not persisted
//  261  Version 10.0 (Current View)1.260       5/25/2006 11:20:02 AM  Durga
//       Brahmandam IDD#4997:Order Access privileges enhacements- method
//       signatures enhanced to distinguish between ItemContainerTypes(order or
//       quote)
//  260  Version 10.0 (Current View)1.259       4/6/2006 4:05:57 PM    Jeff
//       Heigl      IDD#4897: Selector - Head/pressure values being impacted by
//       density
//  259  Version 10.0 (Current View)1.258       4/4/2006 9:00:29 AM    Jeff
//       Heigl      IDD#4787: cache enable flag now pulled from label manager
//       subclass
//  258  Version 10.0 (Current View)1.257       4/4/2006 8:49:57 AM    Jeff
//       Heigl      IDD#4787: Usage of new label cache for back end label
//       variables
//  257  Version 10.0 (Current View)1.256       4/3/2006 3:06:29 PM    Jeff
//       Heigl      IDD#4873: Sort Order - Product Line
//  256  Version 10.0 (Current View)1.255       3/21/2006 11:56:07 AM  Jeff
//       Heigl      IDD#4789: added new detailPage flag, to identify a
//       BEP_RECALC and how its different from a pick FROM_SIZE_LIST
//  255  Version 10.0 (Current View)1.254       2/15/2006 5:23:16 PM   Jeff
//       Heigl      IDD#4394: PD search enhancements for the upgradeVaneSolve
//       and code cleanup
//  254  Version 10.0 (Current View)1.253       2/13/2006 2:29:28 PM   Durga
//       Brahmandam IDD#4755: Selector-configuration navigation failure issue
//       1621: userPreferences.setItemContainerID() call is modified as
//       userPreferences.setQuoteNumber()
//  253  Version 10.0 (Current View)1.252       2/2/2006 5:04:37 PM    Jeff
//       Heigl      IDD#4394: PD's try Metallic curve if Non-metallic is a full
//       reject
//  252  Version 10.0 (Current View)1.251       1/26/2006 9:47:25 AM   Jeff
//       Heigl      IDD#4690: Product option subcat ID's must start with "SC-"?
//  251  Version 10.0 (Current View)1.250       1/25/2006 3:00:21 PM   Jeff
//       Heigl      IDD#4489: Selector - Additional selection contraints
//  250  Version 10.0 (Current View)1.249       12/28/2005 5:36:23 PM  Jeff
//       Heigl      IDD#4569: Ability to generate datasheet-pdf.xml
//  249  Version 10.0 (Current View)1.248       12/16/2005 10:12:17 AM Jeff
//       Heigl      IDD#4569: Ability to generate pdf.xml
//  248  Version 10.0 (Current View)1.247       12/6/2005 2:39:03 PM   Jeff
//       Heigl      IDD#4543: ITO - diaSetItem for AFS is always true
//  247  Version 10.0 (Current View)1.246       11/23/2005 5:20:07 PM  Jeff
//       Heigl      IDD#4502: Trap the condition where the search criteria is
//       variable speed and takeoffCount > 0
//  246  Version 10.0 (Current View)1.245       11/22/2005 11:57:03 AM Jeff
//       Heigl      IDD#4501: ITO UI issues and enhancements
//  245  Version 10.0 (Current View)1.244       11/16/2005 3:53:37 PM  Jeff
//       Heigl      IDD#4426: ITO - Enhanced minimum diameter violation checks
//  244  Version 10.0 (Current View)1.243       11/15/2005 3:14:15 PM  Jeff
//       Heigl      IDD#4501: ITO bug fixes
//  243  Version 10.0 (Current View)1.242       11/14/2005 9:49:29 AM  Jeff
//       Heigl      IDD#4424: ITO Performance Datasheet complete
//  242  Version 10.0 (Current View)1.241       11/1/2005 4:35:46 PM   Jeff
//       Heigl      IDD#4427: Enhanced mixed stage impeller diameter logic
//  241  Version 10.0 (Current View)1.240       10/25/2005 5:50:54 PM  Jeff
//       Heigl      IDD#4412: UI implementation of the advanced data for the
//       additional data page
//  240  Version 10.0 (Current View)1.239       10/21/2005 9:46:24 AM  Jeff
//       Heigl      IDD#4390: added some incrementStages() logic to overcome
//       losses due to performance factors
//  239  Version 10.0 (Current View)1.238       10/19/2005 11:23:24 AM Jeff
//       Heigl      IDD#4408: Support mPa s units for density
//  238  Version 10.0 (Current View)1.237       10/18/2005 2:28:56 PM  Jeff
//       Heigl      IDD#4390: Alternate first stage lost after returning to
//       datasheet
//  237  Version 10.0 (Current View)1.236       10/18/2005 10:02:32 AM Jeff
//       Heigl      IDD#4442: CBI and ITO code cleanup
//  236  Version 10.0 (Current View)1.235       10/12/2005 1:18:38 PM  Jeff
//       Heigl      IDD#4123: Interstage Takeoff (ITO) initial implementation
//  235  Version 10.0 (Current View)1.234       9/9/2005 6:50:02 PM    Jeff
//       Heigl      IDD#4071: imports organized by eclipse
//  234  Version 10.0 (Current View)1.233       9/9/2005 6:03:54 PM    Jeff
//       Heigl      IDD#4071: new CBI architecture
//  233  Version 10.0 (Current View)1.232       7/29/2005 10:10:09 AM  Scott
//       Frees     IDD#4305:  Density values were being parse using Double
//       routines, which expected decimal points
//  232  Version 10.0 (Current View)1.231       6/28/2005 9:12:29 AM   Jeff
//       Heigl      IDD#4275: speedUser read in system units and formatting
//  231  Version 10.0 (Current View)1.230       5/24/2005 10:43:54 AM  Jeff
//       Heigl      null check
//  230  Version 10.0 (Current View)1.229       5/18/2005 4:48:19 PM   Jeff
//       Heigl      IDD#3275: UI changes to handle orders
//  229  Version 10.0 (Current View)1.228       5/17/2005 2:51:21 PM   Jeff
//       Heigl      IDD#3275: integration support for navigation into order
//       manager
//  228  Version 10.0 (Current View)1.227       5/5/2005 10:26:43 AM   Jeff
//       Heigl      IDD#4209: Picking from Thumnails now works like picking
//       from Search Results, and uses the curveNumber
//  227  Version 10.0 (Current View)1.226       4/6/2005 10:11:23 AM   Wayne
//       Hefner    IDD #4158: Corrected issue with handling separator on
//       multiple conditions page
//  226  Version 10.0 (Current View)1.225       3/10/2005 2:47:27 PM   Wayne
//       Hefner    IDD #4109:  Corrected issue with productOption not being
//       saved only for the selected productLine
//  225  Version 10.0 (Current View)1.224       3/9/2005 10:29:49 AM   Jeff
//       Heigl      IDD#4067: XML download enhancements
//  224  Version 10.0 (Current View)1.223       3/3/2005 2:21:15 PM    Wayne
//       Hefner    IDD #4098:  Ensure proper value for solids hardness type is
//       output when displaying item.xml
//  223  Version 10.0 (Current View)1.222       3/2/2005 10:52:04 AM   Wayne
//       Hefner    IDD #4091:  Prevent clicking the start button from resetting
//       the language to english
//  222  Version 10.0 (Current View)1.221       3/1/2005 9:35:22 AM    Wayne
//       Hefner    IDD #4074:  Corrected issue with system curve not converging
//  221  Version 10.0 (Current View)1.220       2/9/2005 4:00:31 PM    Wayne
//       Hefner    IDD #4011: Ensure that all selected productlines are still
//       compatible after processing new COS and appropriate message is
//       displayed when going directly to datasheet
//  220  Version 10.0 (Current View)1.219       2/9/2005 1:23:29 PM    Wayne
//       Hefner    IDD #4011: Ensure that all selected productlines are still
//       compatible after processing new COS
//  219  Version 10.0 (Current View)1.218       2/8/2005 2:36:22 PM    Wayne
//       Hefner    Correct error when navigating from search to datasheet due
//       to a dash being displayed on search results
//  218  Version 10.0 (Current View)1.217       1/31/2005 12:03:55 PM  Wayne
//       Hefner    IDD #3978: Reduce number of PD pumps selected in search
//       results
//  217  Version 10.0 (Current View)1.216       1/11/2005 2:08:30 PM   Wayne
//       Hefner    IDD #3913: Corrected error when retrieving motor selections
//       due to gearSelected not being reset correctly
//  216  Version 10.0 (Current View)1.215       1/6/2005 1:52:56 PM    Wayne
//       Hefner    IDD #3896: Refactor all lightship packages
//  215  Version 10.0 (Current View)1.214       12/21/2004 1:33:46 PM  Wayne
//       Hefner    IDD #3843: Corrected unit conversion when SG is modified but
//       not head or viscosity
//  214  Version 10.0 (Current View)1.213       12/17/2004 1:39:10 PM  Wayne
//       Hefner    IDD #3861: Support multiple condition duty points
//  213  Version 10.0 (Current View)1.212       12/16/2004 12:00:02 PM Wayne
//       Hefner    IDD #3835: Support productLineAutoPick attribute
//  212  Version 10.0 (Current View)1.211       12/16/2004 9:30:13 AM  Wayne
//       Hefner    IDD #3835: Support productLineAutoPick attribute
//  211  Version 10.0 (Current View)1.210       12/16/2004 7:55:18 AM  Wayne
//       Hefner    IDD #3835: Support productLineAutoPick attribute on
//       ProductLine
//  210  Version 10.0 (Current View)1.209       12/15/2004 12:40:46 PM Jeff
//       Heigl      IDD#3852: null pointer fix
//  209  Version 10.0 (Current View)1.208       12/15/2004 12:18:06 PM Jeff
//       Heigl      IDD#3852: speed set fixes
//  208  Version 10.0 (Current View)1.207       12/14/2004 2:56:56 PM  Jeff
//       Heigl      IDD#3830: Overriding the speed (and click on Cancel)
//       doesn't stick 
//  207  Version 10.0 (Current View)1.206       12/14/2004 8:50:41 AM  Wayne
//       Hefner    IDD #3843: Corrected issue with fluidDensity being used
//       prior to setting the correct value when leaving COS page
//  206  Version 10.0 (Current View)1.205       12/10/2004 9:52:29 AM  Wayne
//       Hefner    IDD #3829: Datasheet enhancements for PD pumps
//  205  Version 10.0 (Current View)1.204       12/9/2004 4:09:33 PM   Wayne
//       Hefner    IDD #3829: Datasheet enhancements for PD pumps
//  204  Version 10.0 (Current View)1.203       12/8/2004 1:24:21 PM   Wayne
//       Hefner    IDD #3821: Corrected implementation of performance options
//       due to not recalcing pumpDetails
//  203  Version 10.0 (Current View)1.202       11/22/2004 3:54:43 PM  Wayne
//       Hefner    IDD #3789: Enhancements related to solidsHardnessTypes
//  202  Version 10.0 (Current View)1.201       11/16/2004 11:31:09 AM Wayne
//       Hefner    IDD #3789: UI changes for COS to support PD pumps
//  201  Version 10.0 (Current View)1.200       11/15/2004 2:10:24 PM  Wayne
//       Hefner    IDD #3789: UI changes for COS to support PD pumps
//  200  Version 10.0 (Current View)1.199       11/1/2004 12:48:57 PM  Jeff
//       Heigl      IDD#3690: Enable automatic definition of textbox product
//       options
//  199  Version 10.0 (Current View)1.198       10/26/2004 3:51:29 PM  Jeff
//       Heigl      IDD#3522, 3770: pumpSizeList fixed related to PD pump
//       changes
//  198  Version 10.0 (Current View)1.197       10/26/2004 10:00:44 AM Jeff
//       Heigl      IDD#3770: config buttons refreshed when language has
//       changed
//  197  Version 10.0 (Current View)1.196       10/21/2004 12:04:49 PM Jeff
//       Heigl      IDD#0425: mixedCatalogTrims popup implementation
//  196  Version 10.0 (Current View)1.195       10/19/2004 2:41:49 PM  Wayne
//       Hefner    IDD #3522: Progress towards PD Curves for Multispeed Curves
//  195  Version 10.0 (Current View)1.194       10/18/2004 2:42:06 PM  Wayne
//       Hefner    IDD #3522: Progess towards support of PD curves
//  194  Version 10.0 (Current View)1.193       10/13/2004 8:53:39 AM  Wayne
//       Hefner    IDD #3522: Corrected issue on size list with speeds > 1000
//  193  Version 10.0 (Current View)1.192       10/6/2004 3:04:47 PM   Jeff
//       Heigl      IDD#3468: preferences enhancement
//  192  Version 10.0 (Current View)1.191       10/6/2004 10:07:38 AM  Wayne
//       Hefner    IDD #3522: Support for gear box selections
//  191  Version 10.0 (Current View)1.190       9/30/2004 2:38:05 PM   Wayne
//       Hefner    IDD #3522: Support for PD Pumps
//  190  Version 10.0 (Current View)1.189       9/30/2004 2:21:06 PM   Wayne
//       Hefner    IDD #3522: Support for PD Pumps
//  189  Version 10.0 (Current View)1.188       9/29/2004 9:27:04 AM   Wayne
//       Hefner    IDD #3522: Support for PD Pumps
//  188  Version 10.0 (Current View)1.187       8/20/2004 3:16:58 PM   Wayne
//       Hefner    IDD #0425: Support mixed diameters for multistage pumps
//  187  Version 10.0 (Current View)1.186       8/19/2004 5:18:31 PM   Jeff
//       Heigl      IDD#3690: Enable automatic definition of textbox product
//       options, first steps
//  186  Version 10.0 (Current View)1.185       8/17/2004 3:11:29 PM   Jeff
//       Heigl      IDD#3684: Enhance "Save" options to be as the configurator
//  185  Version 10.0 (Current View)1.184       8/4/2004 5:01:01 PM    Jeff
//       Heigl      IDD#3633: LiquidProperties cast exception fixed
//  184  Version 10.0 (Current View)1.183       8/4/2004 11:36:45 AM   Wayne
//       Hefner    Removed unused imports
//  183  Version 10.0 (Current View)1.182       8/2/2004 10:38:10 AM   Wayne
//       Hefner    IDD #3636: Modified to correct display error for RFQ
//  182  Version 10.0 (Current View)1.181       7/14/2004 4:03:11 PM   Wayne
//       Hefner    IDD #3512: Corrected calculation of PowerReserve after
//       modifying system curve flow or head
//  181  Version 10.0 (Current View)1.180       7/13/2004 3:46:29 PM   Wayne
//       Hefner    IDD #3589: Support user specified maximum specific speed
//       value
//  180  Version 10.0 (Current View)1.179       7/13/2004 1:32:47 PM   Jeff
//       Heigl      IDD#1498: multi-point set to 0 fix
//  179  Version 10.0 (Current View)1.178       7/8/2004 3:55:50 PM    Wayne
//       Hefner    IDD #3183: Display appropriate message when retrieving item
//       from deleted, disabled,  or hidden product lines
//  178  Version 10.0 (Current View)1.177       7/6/2004 10:58:48 AM   Wayne
//       Hefner    IDD #3562: Corrected ClassCast Exception when navigating to
//       Configurator
//  177  Version 10.0 (Current View)1.176       7/2/2004 3:38:52 PM    Wayne
//       Hefner    IDD #3183: Display appropriate message when retrieving item
//       from deleted, disabled,  or hidden product lines
//  176  Version 10.0 (Current View)1.175       7/1/2004 3:25:24 PM    Wayne
//       Hefner    Corrected spelling of behavior
//  175  Version 10.0 (Current View)1.174       6/11/2004 3:47:37 PM   Jeff
//       Heigl      IDD#3438: NavigationFlags variable cleanup
//  174  Version 10.0 (Current View)1.173       6/10/2004 5:10:23 PM   Jeff
//       Heigl      IDD#3512: SC_DriverSize support added to DriverRating page
//  173  Version 10.0 (Current View)1.172       6/10/2004 2:46:15 PM   Jeff
//       Heigl      IDD#3512: SC-DriverSize fixes
//  172  Version 10.0 (Current View)1.171       6/9/2004 10:26:11 AM   Jeff
//       Heigl      IDD#3512:  SC-DriverSize enhancement
//  171  Version 10.0 (Current View)1.170       6/3/2004 11:49:14 AM   Jeff
//       Heigl      IDD#3474: search results log
//  170  Version 10.0 (Current View)1.169       6/2/2004 11:46:56 AM   Jeff
//       Heigl      IDD#3505: dialist units fix for datasheet
//  169  Version 10.0 (Current View)1.168       6/2/2004 10:45:01 AM   Jeff
//       Heigl      IDD#3503: editing bug fixes for KSB datasheet, including
//       solveVariant setValue on operating Conditions
//  168  Version 10.0 (Current View)1.167       5/24/2004 11:18:19 AM  Jeff
//       Heigl      IDD#3481: recalc mode enhancement
//  167  Version 10.0 (Current View)1.166       5/20/2004 4:32:30 PM   Jeff
//       Heigl      IDD#3438: pumpSizeList processing cleaned up
//  166  Version 10.0 (Current View)1.165       5/20/2004 3:06:40 PM   Jeff
//       Heigl      IDD#3438: UserSettings dirty flag enhancement
//  165  Version 10.0 (Current View)1.164       5/18/2004 11:18:20 AM  Jeff
//       Heigl      IDD#3433: chinese language added.  cleaned up language
//       selection.
//  164  Version 10.0 (Current View)1.163       5/17/2004 2:06:49 PM   Jeff
//       Heigl      IDD#2693: NFPA20 modifications
//  163  Version 10.0 (Current View)1.162       5/12/2004 10:24:04 AM  Jeff
//       Heigl      IDD#3228: quoteNumber now displayed instead of
//       itemContainerID
//  162  Version 10.0 (Current View)1.161       5/4/2004 1:50:13 PM    Jeff
//       Heigl      IDD#1498:  Multiple Conditions enhancement
//  161  Version 10.0 (Current View)1.160       4/30/2004 9:25:33 AM   Wayne
//       Hefner    Corrected issue with duplicate port being added to message
//  160  Version 10.0 (Current View)1.159       4/28/2004 1:05:50 PM   Wayne
//       Hefner    IDD #3183: Display appropriate message if product line no
//       longer exists
//  159  Version 10.0 (Current View)1.158       4/28/2004 10:43:00 AM  Jeff
//       Heigl      IDD#3426: temperatureMaxRated replaced with temperatureMax
//  158  Version 10.0 (Current View)1.157       4/12/2004 11:15:25 AM  Jeff
//       Heigl      IDD#2901: LCCLog now has session timeout functionality
//  157  Version 10.0 (Current View)1.156       4/8/2004 3:16:53 PM    Vishnu
//       Akkaraju unused imports variables method non static access fixed
//  156  Version 10.0 (Current View)1.155       4/7/2004 4:01:38 PM    Wayne
//       Hefner    Add CNLWrapper back
//  155  Version 10.0 (Current View)1.154       4/6/2004 4:21:23 PM    Wayne
//       Hefner    IDD #3348: Implementation for Impellers with no diameter
//  154  Version 10.0 (Current View)1.153       4/5/2004 2:15:16 PM    Jeff
//       Heigl      IDD#3348: solve Variant value set fix
//  153  Version 10.0 (Current View)1.152       3/31/2004 9:47:52 AM   Jeff
//       Heigl      IDD#3348: solveVariant impelmentation
//  152  Version 10.0 (Current View)1.151       3/24/2004 3:16:21 PM   Jeff
//       Heigl      IDD#3300: system curve fixes, system curve set at boxes for
//       ksb
//  151  Version 10.0 (Current View)1.150       3/19/2004 6:20:20 PM   Jeff
//       Heigl      IDD#3259: logic removed from JSPs
//  150  Version 10.0 (Current View)1.149       3/16/2004 3:52:07 PM   Wayne
//       Hefner    IDD #3183: Corrected error with retrieving items from
//       deleted product lines
//  149  Version 10.0 (Current View)1.148       3/11/2004 10:23:38 AM  Jeff
//       Heigl      IDD#3300: KSB system curve fix for COS page.
//  148  Version 10.0 (Current View)1.147       2/19/2004 2:30:42 PM   Jeff
//       Heigl      IDD#2448: SVG curve related enhancements
//  147  Version 10.0 (Current View)1.146       1/30/2004 4:22:27 PM   Wayne
//       Hefner    IDD #3110: Supported changing of language for configurator
//       buttons
//  146  Version 10.0 (Current View)1.145       1/21/2004 8:22:04 AM   Mark
//       Glogowski  IDD 2549 Added CatalogTrimsOnly to OC
//  145  Version 10.0 (Current View)1.144       1/12/2004 4:04:33 PM   Jeff
//       Heigl      IDD#0415: NPSHa Calculator screen implementation
//  144  Version 10.0 (Current View)1.143       1/5/2004 9:54:32 AM    Vishnu
//       Akkaraju method name getUserPreferences() on UserXT changed to
//       getUserSettings()
//  143  Version 10.0 (Current View)1.142       1/4/2004 12:34:31 PM   Vishnu
//       Akkaraju ejb replacement with webservices
//  142  Version 10.0 (Current View)1.141       1/3/2004 6:55:29 PM    Vishnu
//       Akkaraju ejb replacement with axis calls
//  141  Version 10.0 (Current View)1.140       12/24/2003 9:54:58 AM  Wayne
//       Hefner    IDD #3010: Support removal of all EJB code from Selector and
//       Version Control
//  140  Version 10.0 (Current View)1.139       12/23/2003 9:52:17 AM  Jeff
//       Heigl      IDD#2506: Make "Quantity of pumps" editable on the
//       Performance Curve page
//  139  Version 10.0 (Current View)1.138       12/16/2003 5:18:19 PM  Jeff
//       Heigl      IDD#2774: performance option textbox values now have a
//       units conversion flag when saved
//  138  Version 10.0 (Current View)1.137       12/5/2003 4:41:51 PM   Jeff
//       Heigl      IDD#2904: fixed advSort when setting criteria2 and 3 to
//       none
//  137  Version 10.0 (Current View)1.136       12/5/2003 3:15:18 PM   Jeff
//       Heigl      IDD#2823: multispeed chart now shows for saved items. 
//       Performance enhancement for saving items from the selector.
//       IDD#2448: SVG image support (not complete)
//  136  Version 10.0 (Current View)1.135       12/4/2003 4:28:15 PM   Jeff
//       Heigl      IDD#2927: orgSetup flags added to append returnURL
//       parameters
//  135  Version 10.0 (Current View)1.134       12/3/2003 10:01:01 AM  Jeff
//       Heigl      IDD#2904: Adv Sort problems resolved, and submit code has
//       been moved into NavigationFlags.java
//  134  Version 10.0 (Current View)1.133       11/21/2003 10:13:56 AM Wayne
//       Hefner    IDD #2850: Corrected issues with saving and retrieving items
//       that were saved on LCC Page
//  133  Version 10.0 (Current View)1.132       11/14/2003 10:45:48 AM Wayne
//       Hefner    IDD #2535: Enabled SOAP call for ItemManager
//  132  Version 10.0 (Current View)1.131       11/13/2003 4:26:27 PM  Jeff
//       Heigl      IDD#0410: misc fixes for the driver rating page
//  131  Version 10.0 (Current View)1.130       11/12/2003 5:18:59 PM  Jeff
//       Heigl      IDD#0410, 2513: driver rating page modifications
//  130  Version 10.0 (Current View)1.129       11/6/2003 5:09:04 PM   Jeff
//       Heigl      IDD#2776: Navigation changes to make all popup windows go
//       thru MainServlet.java
//  129  Version 10.0 (Current View)1.128       10/29/2003 6:19:22 PM  Jeff
//       Heigl      IDD#2552: preferred operating region enhancements
//  128  Version 10.0 (Current View)1.127       10/27/2003 3:53:22 PM  Jeff
//       Heigl      IDD#0410: manual motor selection now working
//  127  Version 10.0 (Current View)1.126       10/23/2003 9:59:29 AM  Jeff
//       Heigl      IDD#2552: preferred operating region added to curve
//       preferences page.  Also moved all curve prefs submit code into
//       NavigationFlags, and allowed curvePrefs to work with viewUIXML.jsp.
//  126  Version 10.0 (Current View)1.125       10/22/2003 1:09:23 PM  Jeff
//       Heigl      IDD#2516: check added before entering configurator
//  125  Version 10.0 (Current View)1.124       10/21/2003 5:28:56 PM  Jeff
//       Heigl      IDD#2422: bug fixes
//  124  Version 10.0 (Current View)1.123       10/16/2003 4:33:01 PM  Jeff
//       Heigl      IDD#0410:  Motor Rating popup implemented, without the
//       ability to manually select the motor
//  123  Version 10.0 (Current View)1.122       10/3/2003 3:34:07 PM   Jeff
//       Heigl      IDD#2712:  new buttons added to the Additional data page
//  122  Version 10.0 (Current View)1.121       10/1/2003 8:33:11 AM   Jeff
//       Heigl      KSB null pointer fix
//  121  Version 10.0 (Current View)1.120       9/26/2003 3:17:49 PM   Jeff
//       Heigl      IDD#2421: Created 'Set @' checkboxes for System Curves #1
//  120  Version 10.0 (Current View)1.119       9/25/2003 9:40:28 AM   Jeff
//       Heigl      IDD#2506: quantity of pumps is now editable for the
//       performance curve page
//  119  Version 10.0 (Current View)1.118       9/24/2003 4:09:59 PM   Jeff
//       Heigl      IDD#2684: clicking custom units now performs an initial
//       submit.
//  118  Version 10.0 (Current View)1.117       9/18/2003 2:58:49 PM   Wayne
//       Hefner    IDD #2672: Corrected Error 500 navigating to Conditions of
//       Service Page
//  117  Version 10.0 (Current View)1.116       9/18/2003 11:53:00 AM  Jeff
//       Heigl      IDD#2669: PumpSizeList impeller dia is now units converted
//  116  Version 10.0 (Current View)1.115       9/16/2003 5:17:17 PM   Jeff
//       Heigl      IDD#1476: "logout" and "save and return" enhancements
//  115  Version 10.0 (Current View)1.114       9/12/2003 4:12:11 PM   Eddie
//       Carr      IDD #2596: Performance enhancements for product lines page
//       and
//       product line options page.
//  114  Version 10.0 (Current View)1.113       9/12/2003 3:58:26 PM   Jeff
//       Heigl      IDD#2607: NullPointerException fix
//  113  Version 10.0 (Current View)1.112       9/11/2003 11:31:55 AM  Jeff
//       Heigl      IDD#2607:  Navigation changes relative to
//       ScreenNames.java's screenMap have been debugged.
//  112  Version 10.0 (Current View)1.111       9/10/2003 4:55:09 PM   Jeff
//       Heigl      IDD#2607: Performance Datasheet's Additional Data page is
//       now implemented.
//  111  Version 10.0 (Current View)1.110       9/5/2003 11:31:40 AM   Jeff
//       Heigl      IDD#2534: Misc enhancements for product line options
//  110  Version 10.0 (Current View)1.109       8/25/2003 12:02:39 PM  Eddie
//       Carr      Fix for submitting performance options from the datasheet
//       page.
//  109  Version 10.0 (Current View)1.108       8/22/2003 4:38:24 PM   Jeff
//       Heigl      IDD#2534: textbox subcategory enhancements
//  108  Version 10.0 (Current View)1.107       8/20/2003 1:49:54 PM   Jeff
//       Heigl      IDD#2534: updates for product Line Subcategory enhancements
//  107  Version 10.0 (Current View)1.106       8/20/2003 10:39:42 AM  Eddie
//       Carr      IDD #2608: Removed passing of ejb flag to item manager
//       calls.
//  106  Version 10.0 (Current View)1.105       8/19/2003 7:41:50 AM   Wayne
//       Hefner    IDD #2592: Corrected error preventing mixed stage data from
//       being persisted when going to sizelist without making a selection
//  105  Version 10.0 (Current View)1.104       8/14/2003 4:21:37 PM   Jeff
//       Heigl      IDD#2534: product line performance options enhancement
//  104  Version 10.0 (Current View)1.103       8/14/2003 2:35:29 PM   Jeff
//       Heigl      IDD#2534: product line performance options enhancement
//  103  Version 10.0 (Current View)1.102       8/8/2003 3:59:42 PM    Eddie
//       Carr      IDD #2575: Support for writing pressure limit of previous
//       material to item xml.
//  102  Version 10.0 (Current View)1.101       8/6/2003 3:22:29 PM    Jeff
//       Heigl      IDD#2410: PDF generic XML enhancement, and save pdf
//       orgSetup enhancement
//  101  Version 10.0 (Current View)1.100       7/31/2003 10:27:53 AM  Jeff
//       Heigl      IDD#2564: Regional settings formatting fix
//  100  Version 10.0 (Current View)1.99        7/25/2003 3:25:48 PM   Jeff
//       Heigl      IDD#2555: altFirstStageID used in Thumbnail Curves Page
//  99   Version 10.0 (Current View)1.98        7/22/2003 4:19:53 PM   Wayne
//       Hefner    IDD #2407: Multi Speed Curve Corrections
//  98   Version 10.0 (Current View)1.97        7/22/2003 10:44:23 AM  Wayne
//       Hefner    IDD #2407: Multi Speed Curve Corrections
//  97   Version 10.0 (Current View)1.96        7/22/2003 10:37:40 AM  Jeff
//       Heigl      IDD#2406: liquid properties page added
//  96   Version 10.0 (Current View)1.95        7/15/2003 4:17:04 PM   Jonathan
//       Lutz   IDD #2422: Fixed tab order for System Data page.  Also
//       implemented Recalculation behavior.
//  95   Version 10.0 (Current View)1.94        7/14/2003 11:32:47 AM  Jonathan
//       Lutz   IDD #2422: Created new System Data tab for COS page.
//  94   Version 10.0 (Current View)1.93        7/11/2003 10:24:43 AM  Wayne
//       Hefner    Replace mistaken checkin
//  93   Version 10.0 (Current View)1.92        7/10/2003 4:40:25 PM   Jonathan
//       Lutz   IDD #2407: Completed UI to enhance multi-speed curves basis
//       flow and head.
//  92   Version 10.0 (Current View)1.91        7/9/2003 1:25:05 PM    Jeff
//       Heigl      IDD#2484: variableSpeed is only set if the parameter is
//       present
//  91   Version 10.0 (Current View)1.90        6/24/2003 11:24:21 AM  Jeff
//       Heigl      units target set to /Party/app/unit
//  90   Version 10.0 (Current View)1.89        6/17/2003 3:36:58 PM   Jeff
//       Heigl      IDD#2284: multistage enhancements
//  89   Version 10.0 (Current View)1.88        6/11/2003 4:39:55 PM   Jeff
//       Heigl      IDD#2371:  PDF's are now opened from the xsl, and
//       guaranteed to load after the content frame is finished
//  88   Version 10.0 (Current View)1.87        6/11/2003 9:57:10 AM   Wayne
//       Hefner    IDD #2141: Backend logic to support advance sort of pump
//       details for search results
//  87   Version 10.0 (Current View)1.86        6/6/2003 3:49:14 PM    Jonathan
//       Lutz   IDD #2259: Changed itemContainerID from int to String in
//       Selector UserPreferences.
//  86   Version 10.0 (Current View)1.85        6/5/2003 9:46:53 AM    Jonathan
//       Lutz   IDD #2259: Header info clean-up.
//  85   Version 10.0 (Current View)1.84        6/4/2003 3:44:35 PM    Jeff
//       Heigl      IDD#2276: item xml download updates
//  84   Version 10.0 (Current View)1.83        6/4/2003 9:57:27 AM    Wayne
//       Hefner    IDD #2265: Modifications to support saving of all PDF files
//       when saving an item
//  83   Version 10.0 (Current View)1.82        5/22/2003 11:34:40 AM  Jeff
//       Heigl      IDD#2021: Recalc to ignore flow and head
//  82   Version 10.0 (Current View)1.81        5/22/2003 10:03:06 AM  Jonathan
//       Lutz   IDD #2213: Fixed bug of speed for default Multi-Speed Curve
//       getting set to zero when not "set" on Perf. Datasheet.
//  81   Version 10.0 (Current View)1.80        5/21/2003 11:23:04 AM  Jonathan
//       Lutz   IDD #2049: Fixed various bugs with Product Line Options UI
//       implementation.
//  80   Version 10.0 (Current View)1.79        5/20/2003 4:19:54 PM   Mark
//       Glogowski  IDD number: 2273 Finished replacing Generate Language
//       Labels with LanguageLabelsManager
//  79   Version 10.0 (Current View)1.78        5/20/2003 2:05:58 PM   Jonathan
//       Lutz   IDD #2263: LCC PDF page implementation.
//  78   Version 10.0 (Current View)1.77        5/19/2003 9:43:08 AM   Jeff
//       Heigl      IDD#2220: Now using ItemManagerClient.java from the
//       ItemManager
//  77   Version 10.0 (Current View)1.76        5/14/2003 4:06:29 PM   Jonathan
//       Lutz   IDD #2049: Product Line Options implemented.
//  76   Version 10.0 (Current View)1.75        5/14/2003 10:57:26 AM  Jeff
//       Heigl      IDD#2184: Old code commented out
//  75   Version 10.0 (Current View)1.74        5/14/2003 8:45:50 AM   Jeff
//       Heigl      IDD#2184: pumpIDSupplier now used instead of pumnpID
//  74   Version 10.0 (Current View)1.73        5/8/2003 5:24:04 PM    Jeff
//       Heigl      IDD#2184: productLineIDSupplier now used instead of
//       productLineID
//  73   Version 10.0 (Current View)1.72        5/7/2003 3:31:06 PM    Wayne
//       Hefner    IDD #2118: Modifications to support using
//       driverServiceFactorFixed as default when coming from sizeList and
//       searchResults
//  72   Version 10.0 (Current View)1.71        5/7/2003 9:27:59 AM    Mark
//       Glogowski  IDD number: 2200 Removed code to make Url parameters
//       caseINsensitive.
//  71   Version 10.0 (Current View)1.70        5/2/2003 11:24:50 AM   Jonathan
//       Lutz   IDD #2143: Put Multi-Speed Curves button on LCC page to allow
//       user to view Multi-Speed Curves with speeds generated from LCC.
//  70   Version 10.0 (Current View)1.69        5/1/2003 4:40:59 PM    Jeff
//       Heigl      IDD#2200:  Re-write of the integration code.
//  69   Version 10.0 (Current View)1.68        4/29/2003 4:15:06 PM   Jonathan
//       Lutz   IDD #2192: Implemented Phase I of Multi-Speed Curves PDFs.
//  68   Version 10.0 (Current View)1.67        4/28/2003 10:02:29 AM  Jonathan
//       Lutz   IDD #0170: Various fixes to currency labels and currency input
//       fields.  Enabled backend to set values as currency with or without the
//       currency symbol.
//  67   Version 10.0 (Current View)1.66        4/28/2003 10:01:45 AM  Jeff
//       Heigl      IDD#2132: now using the pumpDetails tempKey in the to
//       handle the ThumbnailCurves
//  66   Version 10.0 (Current View)1.65        4/25/2003 4:19:55 PM   Jeff
//       Heigl      IDD#2132: fix for hex characters
//  65   Version 10.0 (Current View)1.64        4/25/2003 12:01:12 PM  Jeff
//       Heigl      IDD#2155: Unnecessary session variables removed.
//  64   Version 10.0 (Current View)1.63        4/10/2003 3:10:41 PM   Jeff
//       Heigl      IDD#2067: set the selected pump details in userPreferences
//       in processRejectValidation()
//  63   Version 10.0 (Current View)1.62        4/10/2003 11:54:18 AM  Jeff
//       Heigl      IDD#1959: processNavBar no longer calls
//       processNewSelection, the newSelection is now called by MainServlet
//  62   Version 10.0 (Current View)1.61        4/10/2003 11:41:23 AM  Jeff
//       Heigl      IDD#1959: NewSelection now supported from MainServlet
//  61   Version 10.0 (Current View)1.60        4/7/2003 4:07:33 PM    Wayne
//       Hefner    IDD #0170: Corrected LifeCycleCosts to calculate for the
//       correct head value
//  60   Version 10.0 (Current View)1.59        4/7/2003 9:21:10 AM    Jonathan
//       Lutz   IDD #2059: Multi-Speed Curves UI implementation.
//  59   Version 10.0 (Current View)1.58        4/1/2003 12:51:45 PM   Wayne
//       Hefner    IDD #0170: Life Cycle Cost implementation.
//  58   Version 10.0 (Current View)1.57        3/31/2003 5:43:50 PM   Wayne
//       Hefner    IDD #0170: Modifications for latest LifeCycleCost Changes
//  57   Version 10.0 (Current View)1.56        3/31/2003 9:20:14 AM   Wayne
//       Hefner    IDD #0170 - Support for LifeCycleCosts
//  56   Version 10.0 (Current View)1.55        3/28/2003 2:02:24 PM   Jonathan
//       Lutz   IDD #0170: Life Cycle Cost implementation.
//  55   Version 10.0 (Current View)1.54        3/27/2003 10:51:06 AM  Jonathan
//       Lutz   IDD #0170: LCC implementation.
//  54   Version 10.0 (Current View)1.53        3/25/2003 5:17:41 PM   Wayne
//       Hefner    IDD #0170: Corrected issues with using percentage values
//  53   Version 10.0 (Current View)1.52        3/25/2003 3:24:42 PM   Wayne
//       Hefner    IDD #0170: Modified LifeCycleCost Log Information
//  52   Version 10.0 (Current View)1.51        3/24/2003 2:28:29 PM   Wayne
//       Hefner    IDD #0170: LCC Bug fixes
//  51   Version 10.0 (Current View)1.50        3/24/2003 12:05:43 PM  Jonathan
//       Lutz   IDD #0170: Life Cycle Cost preliminary implementation.
//  50   Version 10.0 (Current View)1.49        3/12/2003 2:24:15 PM   Jeff
//       Heigl      IDD#2048 :isVariableSpeed null check reworked
//  49   Version 10.0 (Current View)1.48        3/11/2003 4:43:03 PM   Jeff
//       Heigl      IDD#2039: Intelliquip name change
//  48   Version 10.0 (Current View)1.47        3/11/2003 3:12:28 PM   Jonathan
//       Lutz   IDD #2035: Fixed bug in which the SelectionKey was always -1
//       (the item ID was not being set) in the returnURL sent back to Flow
//       Products.
//  47   Version 10.0 (Current View)1.46        3/7/2003 8:54:41 AM    Jeff
//       Heigl      IDD#2015:  "Save Successful" msg eliminated
//  46   Version 10.0 (Current View)1.45        3/3/2003 12:35:35 PM   Jonathan
//       Lutz   IDD #0246: Added "Use service factor" and "Service factor"
//       fields to Performance Datasheet page.
//  45   Version 10.0 (Current View)1.44        3/3/2003 9:21:00 AM    Jonathan
//       Lutz   IDD #1959: Set configuration element to null when user clicks
//       New Selection link.
//  44   Version 10.0 (Current View)1.43        2/27/2003 10:19:56 AM  Jonathan
//       Lutz   IDD #1672: Fixed so that back button now works properly when
//       navigating through thumbnail pages.
//  43   Version 10.0 (Current View)1.42        2/19/2003 4:29:34 PM   Jonathan
//       Lutz   IDD #1959: Set configuratorData data member of UserPreferences
//       to null when user clicks New Selection.
//  42   Version 10.0 (Current View)1.41        2/13/2003 2:54:05 PM   Wayne
//       Hefner    added call to clearMixedStagePumps to reset after non mixed
//       selection is made
//  41   Version 10.0 (Current View)1.40        2/13/2003 2:14:02 PM   Wayne
//       Hefner    Corrected issue with selectedCompatiblePump not being reset
//  40   Version 10.0 (Current View)1.39        2/11/2003 10:10:15 AM  Jonathan
//       Lutz   IDD #1736: Added special handling of density for KSB.  Error
//       message now displays when density values are not within limits
//       specified in <densityLimits> element of org-setup.xml.  Validation
//       only occurs when this element is present in org-setup.xml.
//  39   Version 10.0 (Current View)1.38        2/5/2003 11:19:45 AM   Jonathan
//       Lutz   IDD #1690: Made Mixed Stage Performance twistie persist its
//       status during the session.
//  38   Version 10.0 (Current View)1.37        2/4/2003 3:44:22 PM    Jonathan
//       Lutz   IDD #1924: Implementation to allow selection of alternate first
//       stage pumps from Search Results page.
//  37   Version 10.0 (Current View)1.36        1/31/2003 4:01:57 PM   Mark
//       Glogowski  LanguageReasource for alerts msg and status strings
//  36   Version 10.0 (Current View)1.35        1/23/2003 4:20:16 PM   Jeff
//       Heigl      IDD#1870:  "NewSelection" clears out the userPreferences
//       curvePreferences and itinitalizes it with the userDetails curve
//       Preferences.  When setting this, it clones the userDetails
//       curvePreferences so that its a unique copy.
//  35   Version 10.0 (Current View)1.34        1/23/2003 3:08:11 PM   Jonathan
//       Lutz   IDD #1690: Removed "display" attribute for performanceOptions
//       and mixedStagePerformance section elements in org-setup.xml.  No
//       longer setting mixedStagePerformanceEnabled in Operating Conditions. 
//       Modified drop downs on Mixed Stage Performance section in Perf.
//       Datasheet to have "None" value come first.
//  34   Version 10.0 (Current View)1.33        1/22/2003 1:47:43 PM   Eddie
//       Carr      IDD #1844: Fixes for Mixed stage pumps.
//  33   Version 10.0 (Current View)1.32        1/15/2003 12:56:49 PM  Jonathan
//       Lutz   IDD #1682: Fixed variable speed issues relating to the
//       checkboxes on  Performance Datasheet page.
//  32   Version 10.0 (Current View)1.31        1/8/2003 3:08:44 PM    Jeff
//       Heigl      IDD#1802: In processDatasheet, Check if the diaRated is
//       null before doing parseDouble()
//  31   Version 10.0 (Current View)1.30        1/8/2003 11:49:48 AM   Jeff
//       Heigl      IDD#1799: operatingConditions.SPEED_USER is set to zero
//       when theset speed checkbox is unchecked.  Same fix for the stages
//       checkbox.
//  30   Version 10.0 (Current View)1.29        12/27/2002 4:25:44 PM  Jeff
//       Heigl      flow#2 autorecalc additions for the perf datasheet
//  29   Version 10.0 (Current View)1.28        12/19/2002 3:13:46 PM  Jonathan
//       Lutz   IDD #1672: Made use of Debug class to print out debug messages.
//  28   Version 10.0 (Current View)1.27        12/18/2002 2:18:29 PM  Jonathan
//       Lutz   Fixed bug causing a reject when submitting the Performance
//       Datasheet for KSB.  This was caused by setting the stages/speed in
//       Operating Conditions to 0 when StagesSetItemUser/SpeedSetItemUser
//       parameters are not found.
//  27   Version 10.0 (Current View)1.26        12/17/2002 4:57:42 PM  Jonathan
//       Lutz   IDD #1690: Fixed so that NavigationFlags doesn't do Mixed Stage
//       Performance processing for KSB (added hidden field to
//       perfDatasheet.xsl to indicated Mixed Stage Performance is disabled).
//  26   Version 10.0 (Current View)1.25        12/17/2002 1:34:20 PM  Jonathan
//       Lutz   IDD #1711: Fixed problem of ItemNumber integration parameter
//       not being saved.
//  25   Version 10.0 (Current View)1.24        12/16/2002 1:59:43 PM  Jonathan
//       Lutz   IDD #1690: Finished front-end implementation for Mixed Stage
//       Performance section on Performance Datasheet page.
//  24   Version 10.0 (Current View)1.23        12/13/2002 3:45:22 PM  Jeff
//       Heigl      if there is a navBar submit, always end processing 
//  23   Version 10.0 (Current View)1.22        12/10/2002 11:18:36 AM Wayne
//       Hefner    Modified to replace ItemManager SOAP calls with EJB calls
//  22   Version 10.0 (Current View)1.21        12/9/2002 10:17:17 AM  Jeff
//       Heigl      for KSB, the "new selection" processing is now handled by
//       NavFlags.java, similar to intellequip
//  21   Version 10.0 (Current View)1.20        12/6/2002 4:50:43 PM   Jeff
//       Heigl      revisions to make browser back button work properly
//  20   Version 10.0 (Current View)1.19        12/6/2002 10:05:13 AM  Jonathan
//       Lutz   IDD #1530: Fix to prevent NumberFormatException when HomeOrigin
//       is not set when Start Page is submitted (i.e. when changing the
//       language).
//  19   Version 10.0 (Current View)1.18        12/5/2002 3:29:33 PM   Eddie
//       Carr      IDD #1242: Support for displaying search results for pumps
//       that have multiple selections for the same speed and stages but a
//       different curve.
//  18   Version 10.0 (Current View)1.17        12/5/2002 2:49:00 PM   Jonathan
//       Lutz   IDD #1530: Added <languages> element to org-setup.xml.  Added
//       functionality in StartPage.java, startPage.xsl, and
//       NavigationFlags.java to handle language selection.
//  17   Version 10.0 (Current View)1.16        12/4/2002 5:12:46 PM   Wayne
//       Hefner    FOP vars added for datasheet and curve submits
//  16   Version 10.0 (Current View)1.15        12/4/2002 2:09:03 PM   Eddie
//       Carr      IDD #1682: Corrected various issues with variable speed
//       selections.
//  15   Version 10.0 (Current View)1.14        12/3/2002 4:16:43 PM   Eddie
//       Carr      IDD #1635: Support for variable speed selections.
//  14   Version 10.0 (Current View)1.13        12/3/2002 12:03:59 PM  Jonathan
//       Lutz   IDD #1567: Fixed so that speed, stages, and diameter are
//       sending the correct "engine" (metric) values to operating conditions
//       to eliminate full rejects on the Performance Datasheet Page.
//  13   Version 10.0 (Current View)1.12        12/3/2002 9:16:17 AM   Jeff
//       Heigl      now has the capability to display alert messages.  The msgs
//       are determined by NavigationFlags.java and stored in the session as a
//       vector, and are retrieved by main.jsp and displayed.
//  12   Version 10.0 (Current View)1.11        11/27/2002 3:37:52 PM  Eddie
//       Carr      IDD #1465: Corrections for variable speed selections.
//  11   Version 10.0 (Current View)1.10        11/27/2002 10:21:40 AM Jonathan
//       Lutz   IDD #1635: Added null check for SpeedCriteriaItemUser parameter
//       in processPerformanceDatasheet() method.
//  10   Version 10.0 (Current View)1.9         11/26/2002 11:49:42 AM Jonathan
//       Lutz   IDD #1635: Added Speed criteria selection to Performance
//       Datasheet page, which now passes this value to the Operating
//       Conditions in NavigationFlags.java.
//  9    Version 10.0 (Current View)1.8         11/25/2002 10:53:13 AM Jeff
//       Heigl      COS, Datasheet additions to save customerName, customerRef
//       fields
//  8    Version 10.0 (Current View)1.7         11/21/2002 2:09:53 PM  Jonathan
//       Lutz   IDD #1567: Implemented front end for enabling user-defined
//       speed, stages, and diameter on Pump Size List page.
//  7    Version 10.0 (Current View)1.6         11/19/2002 3:53:50 PM  Jeff
//       Heigl      OrgSetup constructor changed
//  6    Version 10.0 (Current View)1.5         11/18/2002 1:41:20 PM  Jonathan
//       Lutz   IDD #1567: Front end implementation for Pump Size List display
//       types.
//  5    Version 10.0 (Current View)1.4         11/8/2002 1:14:30 PM   Jonathan
//       Lutz   IDD #1569: Renamed UISetup variables/class references to
//       OrgSetup.
//  4    Version 10.0 (Current View)1.3         10/31/2002 1:47:20 PM  Jeff
//       Heigl      debug mode turned off
//  3    Version 10.0 (Current View)1.2         10/29/2002 2:08:06 PM  Jeff
//       Heigl      uses new UISetup constructor
//  2    Version 10.0 (Current View)1.1         10/28/2002 2:44:42 PM  Jeff
//       Heigl      start page error check
//  1    Version 10.0 (Current View)1.0         10/24/2002 11:24:13 AM Jeff
//       Heigl      
// $
// $NoKeywords$
////////////////////////////////////////////////////////////////////////////////

package com.intelliquip.hydraulicselection.control.web;

import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.intelliquip.chart.data.ChartHeader;
import com.intelliquip.compressor.CompressorUser;
import com.intelliquip.compressor.CurrentSearchResults;
import com.intelliquip.compressor.SelectedModelList;
import com.intelliquip.compressor.Selections;
import com.intelliquip.compressor.conditions.CompressorConditionsOfService;
import com.intelliquip.compressor.conditions.CompressorMultipleConditions;
import com.intelliquip.compressor.conditions.Condition;
import com.intelliquip.compressor.conditions.EnabledConditions;
import com.intelliquip.compressor.conditions.VarSpeedPowerData;
import com.intelliquip.compressor.conditions.gas.GasConstituentsActual;
import com.intelliquip.compressor.conditions.gas.GasProperties;
import com.intelliquip.compressor.search.CompressorSearchFacade;
import com.intelliquip.compressor.search.DatasheetMode;
import com.intelliquip.compressor.search.SizeListSelection;
import com.intelliquip.compressor.search.SizeListSelectionImpl;
import com.intelliquip.constants.ItemContainerTypeConstants;
import com.intelliquip.constants.PdfPage;
import com.intelliquip.core.Attributes;
import com.intelliquip.core.SearchCriteria;
import com.intelliquip.core.SolveVariant;
import com.intelliquip.core.SpeedCriteria;
import com.intelliquip.core.UserSettings;
import com.intelliquip.core.cbi.Wrapper;
import com.intelliquip.core.compatibilityrule.CompatibilityRuleException;
import com.intelliquip.core.curve.CurvePreferences;
import com.intelliquip.core.curve.CurveStyle;
import com.intelliquip.core.curve.SystemCurve;
import com.intelliquip.core.headloss.HeadLoss;
import com.intelliquip.core.headloss.InputData;
import com.intelliquip.core.headloss.SystemTypePicklist;
import com.intelliquip.core.headloss.HeadLossConstants.FittingSection;
import com.intelliquip.core.headloss.HeadLossConstants.FrictionCalcStrategy;
import com.intelliquip.core.headloss.HeadLossConstants.NominalPipeSizeUnits;
import com.intelliquip.core.qmconfig.Fld_Application_List;
import com.intelliquip.core.save.SaveTypes;
import com.intelliquip.core.xml.XMLDocument;
import com.intelliquip.hydraulicselection.CompatiblePumpSelected;
import com.intelliquip.hydraulicselection.FluidDensityAdjustment;
import com.intelliquip.hydraulicselection.Item;
import com.intelliquip.hydraulicselection.LifeCycleCost;
import com.intelliquip.hydraulicselection.LifeCycleCostLoadProfile;
import com.intelliquip.hydraulicselection.LiquidPropertiesPageSettings;
import com.intelliquip.hydraulicselection.MotorDriverRatingSettings;
import com.intelliquip.hydraulicselection.NPSHAvailableCalculator;
import com.intelliquip.hydraulicselection.OperatingConditions;
import com.intelliquip.hydraulicselection.PumpDetails;
import com.intelliquip.hydraulicselection.PumpDetailsSortCriteria;
import com.intelliquip.hydraulicselection.PumpSetConditions;
import com.intelliquip.hydraulicselection.PumpSetConditionsImpl;
import com.intelliquip.hydraulicselection.SelectorCategory;
import com.intelliquip.hydraulicselection.SelectorPerformanceOption;
import com.intelliquip.hydraulicselection.SelectorSubcategory;
import com.intelliquip.hydraulicselection.SolidsHardnessType;
import com.intelliquip.hydraulicselection.UserPreferences;
import com.intelliquip.hydraulicselection.api610.API610MaxWorkingPressureSettings;
import com.intelliquip.hydraulicselection.api610.API610Settings;
import com.intelliquip.hydraulicselection.api610.HeadIncreaseCriteria;
import com.intelliquip.hydraulicselection.api610.MaxContinuousSpeedCriteria;
import com.intelliquip.hydraulicselection.api610.MaxWorkingPressureEdition;
import com.intelliquip.hydraulicselection.api610.MaxWorkingPressureType;
import com.intelliquip.hydraulicselection.api610.StableHeadFlowRateCriteria;
import com.intelliquip.hydraulicselection.chart.axis.PageSettingsCollection;
import com.intelliquip.hydraulicselection.chart.constant.SelectorChartType;
import com.intelliquip.hydraulicselection.curve.MultiSpeedCurveSelected;
import com.intelliquip.hydraulicselection.headloss.HeadLossFacade;
import com.intelliquip.hydraulicselection.headloss.submit.FittingSelectionSubmit;
import com.intelliquip.hydraulicselection.headloss.submit.FittingSubmitFacade;
import com.intelliquip.hydraulicselection.headloss.submit.HeadLossFittingSubmit;
import com.intelliquip.hydraulicselection.headloss.submit.SpecialFittingSubmit;
import com.intelliquip.hydraulicselection.integration.SelectorPDF;
import com.intelliquip.hydraulicselection.multiconditions.MultipleConditionsSubmitReader;
import com.intelliquip.hydraulicselection.organization.OrgSetup;
import com.intelliquip.hydraulicselection.productline.ProductLine;
import com.intelliquip.hydraulicselection.productline.ProductOptionsUser;
import com.intelliquip.hydraulicselection.productline.model.ProductLineModel;
import com.intelliquip.hydraulicselection.productline.web.ProductLineWebImpl;
import com.intelliquip.hydraulicselection.search.RevisedSearchCache;
import com.intelliquip.hydraulicselection.util.Debug;
import com.intelliquip.hydraulicselection.util.SelectorSaveParamProcessor;
import com.intelliquip.labels.PageLanguageUI;
import com.intelliquip.performanceoptions.AutoUpgradeOption;
import com.intelliquip.performanceoptions.SubcategoryConstants;
import com.intelliquip.serviceclient.ItemClient;
import com.intelliquip.serviceclient.UserClient;
import com.intelliquip.unitofmeasure.Measure;
import com.intelliquip.unitofmeasure.UnitOfMeasure;
import com.intelliquip.unitofmeasure.UnitOfMeasureFacade;
import com.intelliquip.util.EnumUtils;
import com.intelliquip.util.FailFastHandler;
import com.intelliquip.util.HttpParamUtils;
import com.intelliquip.util.NumberUtils;
import com.intelliquip.util.ParameterMap;
import com.intelliquip.util.StringUtils;
import com.sun.istack.internal.ByteArrayDataSource;

public class NavigationFlags {
	/**
	 * Logger for this class
	 */
	private static final Logger log = Logger.getLogger(NavigationFlags.class);

	//debug parameter that prints the current screen to System.err
	private final static boolean DEBUG_CURRENTSCREEN = false;
	private final static boolean DEBUG_TARGETPAGE = false;

	//primary vars, initialized by the constructor
	private HttpServletRequest request = null;
	private HttpSession session = null;
	private UserPreferences userPreferences = null;
	private ProductLineWebImpl productLineWeb = null;

	//secondary vars, initialized from primary vars
	/**
	 * When appending GET parameters to this url, simply use '&' because the main.jsp will already use a '?' when appending this target page parameter
	 */
	private String targetPage = null;
	private String originalTargetPage = null; // save targetPage to revert back to if necessary
	private UserSettings userSettings = null;
	private int currentScreen = -1;
	private boolean doRejectValidation = false;
	private SessionAttributeDAO_Selector dao;
	//private String newLang = null;
	String contextPath = null;
	String serverName = null;
	int languageID = 1;
	boolean isIEQAdvancedUser = false;
	boolean isKSBUser = false;
	boolean isIEQBasicUser = false;
	String servletPath = null;
	String targetPath = null;

	//vars completely determined at runtime
	List<String> alert = null;

	PageLanguageUI pageLabels = null;

	// used to process thumbnail pages
	private String thumbnailPageParam = "";

	/** Constructor, inits primary vars */
	public NavigationFlags(HttpServletRequest request, HttpSession session) {

		alert = new ArrayList<String>();
		this.request = request;
		this.session = session;

		// use the vars instantiated above to initialize the secondary vars
		dao = new HttpSessionAttributeDAO_Selector(request.getSession());
		initializeSecondaryVars();

	}

	/** inits secondary vars, using primary vars */
	private void initializeSecondaryVars() {

		userPreferences = dao.getUserPreferences(); //---must add null check!!!
		userSettings = userPreferences.getUserSettings();

		this.productLineWeb = dao.getProductLineWeb();
		if(productLineWeb == null) {
			productLineWeb = new ProductLineWebImpl();
		}

		targetPage = request.getParameter("TargetPage");
		originalTargetPage = targetPage;
		if(DEBUG_TARGETPAGE || Debug.debuggingOn) {
			System.err.println("NavigationFlags.java: originalTargetPage="+originalTargetPage);
		} //resolved statically

		String currentPage = request.getParameter("CurrentPage");
		if(currentPage != null) {
			//this variable is only needed below to get the current screen
			currentScreen = ScreenNames.getScreenIDByURL(currentPage);
		}

		int orgID = userPreferences.getOrgID();
		languageID = userPreferences.getUserSettings().getLanguageID();

		pageLabels = userPreferences.getLabelManager().getPageLanguageUI(ScreenNames.NAVIGATION_SCREEN,languageID);


		// See if reject validation should be done before calling a configurator link
		String rejectValidation = request.getParameter("DoRejectValidation");
		if(rejectValidation != null && rejectValidation.length() > 0) {
			doRejectValidation = stringToBoolean(rejectValidation);
		}

		serverName = "http://" + request.getServerName();
		int serverPort = request.getServerPort();
		if(serverPort != 80) {
			serverName += ":" + serverPort;
		}

		contextPath = request.getContextPath();

		if(userSettings != null) {
			languageID = userSettings.getLanguageID();
		}

		isIEQAdvancedUser = userPreferences.isUserInGroup("IEQAdvanced");
		isIEQBasicUser = userPreferences.isUserInGroup("IEQBasic");
		isKSBUser = userPreferences.isUserInGroup("KSBUsers");

		servletPath = (String) (request.getAttribute("servletPath"));
		if(servletPath == null) {
			servletPath = "/App";
		}

		targetPath = contextPath + servletPath;
	}

	/** Calls the appropriate method for the processing of the currentScreen, which is retrieved from the already initialized HTTPServletRequest object.
	 *  Calls the appropriate method(s) for the processing of the special flags.
	 *  Performs the generic, screen independent code.
	 *  The return String indicates the next target URL (/IEQ_HydSel/HydSel_JSP/App/performancedatasheet ...for example). */
	public String processCurrentScreen() {
		// ---check if NavBar requires processing---
		String navBarSubmit = request.getParameter("NavBarSubmit");
		if (navBarSubmit != null) {
			FailFastHandler.doFailFast("Selector NavBar is doing a submit.  This should not be happening.");
		} else {
			processNonNavBarScreens();
		}

		// ---generic, screen independent code---
		processDisplayCurvePrefWindow();
		saveUserSettingsToPartyIfDirty();
		logTargetPageForDebugging();
		addAlertListToSession();

		return targetPage;
	}

	private void processNonNavBarScreens() {
		logCurrentScreenForDebugging();

		if(DisplayController.isSupportedByDisplayServlet(currentScreen)) {
			DisplayController.processPageSubmit(currentScreen, this);
		} else {
			processSubmitForLegacyPages();
		}

		processSpecialFlags();

		if(doRejectValidation) {
			processRedirectConfig();
		}
	}

	private void processRedirectConfig() {
		RedirectApp redirectApp = createRedirectApp();
		try {
			targetPage = redirectApp.prepareForRedirect();
		} catch(RedirectValidationException e) {
			alert.add(e.getUserErrorMessage());
			targetPage = e.getUrl();
		}
	}

	private RedirectApp createRedirectApp() {
		RedirectParams parameterObject = new RedirectParams(request, userPreferences, productLineWeb, pageLabels, serverName, targetPath, currentScreen);
		return RedirectAppFactory.buildRedirect(request, userPreferences, parameterObject);	}

	/**
	 * Calls the appropriate method for the processing for the currentScreen.
	 * note that these functions may modify the value of targetPage
	 */
	private void processSubmitForLegacyPages() {
		switch(currentScreen) {
			case ScreenNames.START_PAGE_SCREEN:
				processStartPage();
				break;
			case ScreenNames.CONDITIONS_OF_SERVICE_SCREEN:
				processCOS();
				break;
			case ScreenNames.SYSTEM_DATA_SCREEN:
				processSystemData();
				break;
			case ScreenNames.PRODUCT_LINES_SCREEN:
				processProductLines();
				break;
			case ScreenNames.PRODUCT_LINE_OPTIONS_SCREEN:
				processProductLineOptions();
				break;
			case ScreenNames.SEARCH_RESULTS_SCREEN:
				processSearchResults();
				break;
			case ScreenNames.PUMP_SIZE_LIST_SCREEN:
				processPumpSizeList();
				break;
			case ScreenNames.PERFORMANCE_DATASHEET_SCREEN:
				processPerformanceDatasheet();
				break;
			case ScreenNames.LIFE_CYCLE_COST_SCREEN:
				processLifeCycleCost();
				break;
			case ScreenNames.PERFORMANCE_CURVE_SCREEN:
				processPerformanceCurve();
				break;
			case ScreenNames.MULTI_SPEED_CURVES_SCREEN:
				processMultiSpeedCurves();
				break;
			case ScreenNames.THUMBNAIL_CURVES_SCREEN:
				processThumbnailCurves();
				break;
			case ScreenNames.DATASHEET_ADDITIONAL_DATA_SCREEN:
				processAdditionalDataPage();
				break;
			case ScreenNames.DRIVER_RATING_SCREEN:
				processDriverRatingPage();
				break;
			/*case ScreenNames.CURVE_PREFS_SCREEN:
				processCurvePreferencesPage();
				break;*/
			case ScreenNames.ADVANCED_SORT_SCREEN:
				processAdvSortPage();
				break;
			case ScreenNames.NPSH_AVAILABLE_SCREEN:
				processNPSHAvailablePage();
				break;
			case ScreenNames.LIQUID_PROPERTIES_SCREEN:
				processLiquidPropertiesPage();
				break;
			case ScreenNames.MULTIPLE_CONDITIONS_SCREEN:
				processMultipleConditionsCOS();
				break;
			case ScreenNames.ITO_CONDITIONS_OF_SERVICE_SCREEN:
				processITOConditonsOfServicePage();
				break;
			case ScreenNames.DATASHEET_ITO_SCREEN:
				processITODatasheetPage();
				break;
			case ScreenNames.MOTOR_PERFORMANCE_SCREEN:
				processMotorPerformanceDatasheetPage();
				break;
			case (ScreenNames.HEAD_LOSS_SCREEN):
				processHeadLossPage();
				break;
			case (ScreenNames.FITTING_SELECTION_SCREEN):
				processFittingSelectionPage();
				break;
			case (ScreenNames.SPECIAL_FITTING_SCREEN):
				processSpecialFittingPage();
				break;
			case (ScreenNames.ROUGHNESS_SCREEN):
			case (ScreenNames.C_FACTOR_SCREEN):
				System.err.println("NavigationFlags.processCurrentScreen() is not yet implemented for "+ScreenNames.getURLByScreenID(currentScreen));
				break;
			case ScreenNames.CURVE_COMMENT_SCREEN:
				processCurveCommentPage();
				break;
			case ScreenNames.API610_POPUP_SCREEN:
				processApi610Page();
				break;
			case ScreenNames.MULTIPLE_CONDITIONS_DATASHEET_SCREEN:
				processMultipleConditionsDatasheet();
				break;
		}
	}

	private void processSpecialFlags() {
		appendScrollPositionYToTargetPage();
		checkAndSaveItem();
	}

	private void appendScrollPositionYToTargetPage() {
		boolean isRecalc = Boolean.valueOf(request.getParameter("isRecalcSubmit"));
		if(isRecalc) {
			targetPage += ("&positionY=" + request.getParameter("positionY"));
		}
	}

	private void checkAndSaveItem() {
		boolean saveItem = Boolean.valueOf(request.getParameter("SaveItem"));
		if(saveItem) {
			//Check if they have the priviledge to save an item
			//They should, otherwise the 'save' button should be disabled
			if(userPreferences.getItemSavePriviledge()) {
				processSaveItem();
				String afterSaveTargetUrl = request.getParameter("AfterSaveTargetUrl");
				if(StringUtils.isDefined(afterSaveTargetUrl)) {
					targetPage = afterSaveTargetUrl;
				}
			} else {
				String label = pageLabels.getLabel("noSavePriviledge");
				alert.add(label);
			}
		}
	}

	private void saveUserSettingsToPartyIfDirty() {
		if(userSettings.isDirty()) {
			try {
				userPreferences.setPumpDetailsRecalcNeeded(true);  //must recalc the pump
				UserClient.putUserSettings(userPreferences.getUser().getDynamicID(), userSettings.writeXMLText()); //store userSettings for retrieval by other apps
				userSettings.setDirty(false);
			} catch(Exception ex) {
				ex.printStackTrace();
			}
		}
	}

	private void addAlertListToSession() {
		if(!alert.isEmpty()) {
			dao.setAlertVector(alert);
		}
	}

	private void logTargetPageForDebugging() {
		if (DEBUG_TARGETPAGE || Debug.debuggingOn) {
			System.err.println("NavigationFlags.java: targetPage=" + targetPage);
		}
	}

	private void logCurrentScreenForDebugging() {
		if (DEBUG_CURRENTSCREEN || Debug.debuggingOn) {
			String currentScreenName = null;
			try {
				// statically resolved
				currentScreenName = ScreenNames.getURLByScreenID(currentScreen) + " screen";
			} catch (RuntimeException e) {
				currentScreenName = "Invalid screen ID " + currentScreen;
			}
			System.err.println("NavigationFlags.java: " + currentScreenName);
		}
	}

	void processApi610Page() {
		API610Settings api610 = userPreferences.getOperatingConditions().getApi610Settings();
		API610MaxWorkingPressureSettings wpSettings = api610.getApi610MaxWorkingPressureSettings();
		String headIncreaseCriteria = request.getParameter("headIncreaseCriteria");
		String maxContinuousSpeedCriteria = request.getParameter("maxContinuousSpeedCriteria");
		String stableHeadFlowRateCriteria = request.getParameter("stableHeadFlowRateCriteria");
		String maxWorkingPressureType = request.getParameter("maxWorkingPressureType");
		String maxWorkingPressureEdition = request.getParameter("maxWorkingPressureEdition");

		String maximumImpellerEnabled = request.getParameter("maximumImpellerEnabled");
		String blankStagesEnabled = request.getParameter("blankStagesEnabled");
		String blankStages = request.getParameter("blankStages");
		String tripSpeedEnabled = request.getParameter("tripSpeedEnabled");
		String tripSpeed = request.getParameter("tripSpeed");

		api610.setHeadIncreaseCriteria(EnumUtils.valueOfSafely(HeadIncreaseCriteria.class, headIncreaseCriteria, HeadIncreaseCriteria.LARGER_IMPELLER));
		api610.setStableHeadFlowRateCriteria(EnumUtils.valueOfSafely(StableHeadFlowRateCriteria.class, stableHeadFlowRateCriteria, StableHeadFlowRateCriteria.NOT_REQUIRED));
		api610.setMaxContinuousSpeedCriteria(EnumUtils.valueOfSafely(MaxContinuousSpeedCriteria.class, maxContinuousSpeedCriteria, MaxContinuousSpeedCriteria.SYNCHRONOUS_SPEED));

		wpSettings.setMaxWorkingPressureType(EnumUtils.valueOfSafely(MaxWorkingPressureType.class, maxWorkingPressureType, MaxWorkingPressureType.RATED_DENSITY));
		wpSettings.setMaxWorkingPressureEdition(EnumUtils.valueOfSafely(MaxWorkingPressureEdition.class, maxWorkingPressureEdition, MaxWorkingPressureEdition.TENTH_EDITION));
		wpSettings.setMaximumImpellerEnabled(Boolean.parseBoolean(maximumImpellerEnabled));
		wpSettings.setBlankStagesEnabled(Boolean.parseBoolean(blankStagesEnabled));
		wpSettings.setTripSpeedEnabled(Boolean.parseBoolean(tripSpeedEnabled));
		int blankStagesValue = NumberUtils.parseIntSafely(blankStages, 0);
		if (blankStagesValue < 0) {
			blankStagesValue = 0;
		}
		wpSettings.setBlankStages(blankStagesValue);
		int tripSpeedValue = NumberUtils.parseIntSafely(tripSpeed, 0);
		if (tripSpeedValue < 0) {
			tripSpeedValue = 0;
		}
		wpSettings.setTripSpeed(tripSpeedValue);

		//validate to make sure the eighthEdition params are set correctly
		wpSettings.validateSettingsBaseOnEdition();
	}

	private void processSaveItem() {
		
		try {
			SelectorSaveParamProcessor saveParamProcessor = new SelectorSaveParamProcessor(request, userPreferences);
			
			userPreferences.setDisplayPage(currentScreen);
			/*
			 * IDD#7965: must update the lastModified date to today's date before generating the
			 * itemXML.
			 */
			userPreferences.setLastModifiedDate(new Date());
			Item item = new Item(userPreferences);
			
			String xmlString = userPreferences.writeItemXMLString();
			String savedItem = null;
			if(userPreferences.getItemID() > 0) {
				 //delete all existing Item docs first.
				ItemClient.deleteItemDocuments(userPreferences.getUser().getID(), userPreferences.getItemID());
				savedItem = ItemClient.updateItem(userPreferences.getUser().getDynamicID(), userPreferences.getItemID(), xmlString, userPreferences.getIqxXml(), userPreferences.getItemContainerTypeCode(), false, saveParamProcessor.isQuickSave());
			} else {
				savedItem = ItemClient.saveItem(userPreferences.getUser().getDynamicID(), xmlString, userPreferences.getIqxXml(), true, ItemContainerTypeConstants.QUOTE_MANAGER, saveParamProcessor.isQuickSave());
			}
			
			XMLDocument savedDoc = new XMLDocument();
			savedDoc.read(savedItem);

			item.update(savedDoc.getDocumentElement());

			// determine targetPage
			String itemURL = contextPath + "/SaveSettingsRedirect?destAppTarget=itemmanager/app/start";
			if (saveParamProcessor.getSaveType() == null) {
				SessionAttributeDAO_Selector dao = new HttpSessionAttributeDAO_Selector(request.getSession());
				String ifeLogoutAndTimeoutURL =dao.getIfeLogoutAndTimeoutURL();
				if (!StringUtils.isDefined(ifeLogoutAndTimeoutURL)) {
					// return to page user was on when clicking save link
					targetPage = originalTargetPage;
				} else {
					//this is a "save and return", set targetPage as LogoutJSP
					targetPage = serverName + contextPath + "/" + ScreenNames.LOGOUT_JSP + "?logoutAfterSave=true";
				}

			} else if (saveParamProcessor.getSaveType() == SaveTypes.QuickSave) {
				targetPage = originalTargetPage;
			} else if (saveParamProcessor.getSaveType() == SaveTypes.Save) {
				targetPage = originalTargetPage;
			} else if (saveParamProcessor.getSaveType() == SaveTypes.SaveAndReturnToQuoteDetails) {
				//default to "quote details page"
				targetPage = itemURL + "&Tab=1&dynamicID=" + userPreferences.getUser().getDynamicID() + "&SelectedItemContainerID=" + userPreferences.getItemContainerID() + "&bannerType="+userPreferences.getItemContainerTypeCode();
			} else if (saveParamProcessor.getSaveType() == SaveTypes.SaveAndReturnToOrderDetails) {
				//this item is part of an order, forward to "order details page"
				targetPage = itemURL + "&Tab=12&dynamicID=" + userPreferences.getUser().getDynamicID() + "&SelectedItemContainerID=" + userPreferences.getItemContainerID() + "&bannerType="+userPreferences.getItemContainerTypeCode();
			} else if (saveParamProcessor.getSaveType() == SaveTypes.SaveAndReturnToQuoteDocs) {
				targetPage = itemURL + "&Tab=4&dynamicID=" + userPreferences.getUser().getDynamicID() + "&SelectedItemContainerID=" + userPreferences.getItemContainerID() + "&bannerType="+userPreferences.getItemContainerTypeCode();
			}

			// Save all selector pdf's
			if(saveParamProcessor.isSavePDFs()) {
				SelectorPDF.generateAndSaveAllPDFsUsingOrgSetup(userPreferences);
			}

			if (saveParamProcessor.isDeactiveOrigItem()) {
				int itemContainerID = NumberUtils.parseIntSafely(userPreferences.getItemContainerID(), 0);
				ItemClient.deactivateQuoteItem(itemContainerID, saveParamProcessor.getOldItemID());
			}

			if (saveParamProcessor.isAlternateTo() && userPreferences.getItemID() > 0) {
				ItemClient.updateItemAlternateTo(userPreferences.getItemID(), saveParamProcessor.getOldItemID());
			}
		} catch(Exception ex) {
			String label = pageLabels.getLabel("saveFailedContact");
			alert.add(label);
			ex.printStackTrace();
		}
	}

	//allow MainServlet to use this method
	public static void processNewSelection(UserPreferences userPreferences, String serverName, String contextPath) {
		if(userPreferences != null) {
			//new selection, wipe out the operating conditions
			userPreferences.resetNavigationFlags();   //calls resetOperatingConditions()

			// set configurator data, configuration element to null for new selection
			userPreferences.setConfiguratorData(null);
			userPreferences.setConfiguration(null);

			// re-initialize the org-setup XML for userPreferences
			try {
				String orgFolderHome = userPreferences.getFolderHome();
				String orgSetupXML = serverName + contextPath + "/" + orgFolderHome + "xml/org-setup.xml";
				URL orgSetupURL = new URL(orgSetupXML);
				userPreferences.initOrgSetup(orgSetupURL);    //read in the org-setup.xml file again
			} catch(Exception ex) {
				ex.printStackTrace();
			}
		}
	}

	private void processDisplayCurvePrefWindow() {
		// check for a CurvePrefWindow popup window request
		String popupURL = request.getParameter("DisplayCurvePrefWindow");
		if (popupURL != null && popupURL.equals("true")) {
			targetPage += "&displayCurvePrefWindow=true";
			userSettings.setDirty(true); // force a putUserSettings
		}
	}

	/** performs the processing for the StartPage*/
	void processStartPage() {

		// see if StartPage is attempting to switch languages (Intelliquip UI organizations)
		String languageCodeDirty = request.getParameter("LanguageCodeDirty");
		if(languageCodeDirty!=null && languageCodeDirty.equals("true")) {
			String languageCode = request.getParameter( "LanguageCode");
			if (languageCode != null && languageCode.length() > 0) {
				this.userSettings.setLanguageCode(languageCode);
				this.userPreferences.getOrgSetup().setButtons(null);  //must retrieve the config buttons in the new language
			}
		}

		String homeOrigin = request.getParameter("HomeOrigin");
		if(homeOrigin != null && homeOrigin.length() > 0) {
			userPreferences.setHomeOrigin(Integer.parseInt(homeOrigin));
		}
	}

	/** performs the processing for the StartPage*/
	void processCompressorStartPage() {

		// see if StartPage is attempting to switch languages (Intelliquip UI organizations)
		String languageCodeDirty = request.getParameter("LanguageCodeDirty");
		if(languageCodeDirty!=null && languageCodeDirty.equals("true")) {
			String languageCode = request.getParameter("LanguageCode");
			if (languageCode != null && languageCode.length() > 0) {
				this.userSettings.setLanguageCode(languageCode);
				this.userPreferences.getOrgSetup().setButtons(null);  //must retrieve the config buttons in the new language
			}
		}

		String homeOrigin = request.getParameter("HomeOrigin");
		if(homeOrigin != null && homeOrigin.length() > 0) {
			userPreferences.setHomeOrigin(Integer.parseInt(homeOrigin));
		}
	}

	/**
	 * performs the processing for the COS page
	 */
	void processSystemData() {
		OperatingConditions oc = userPreferences.getOperatingConditions();
		String temp = "";

		//check for a popup window request
		temp = request.getParameter("DisplayCustomUOMWindow");
		if(temp != null && temp.equals("true")) {
			targetPage += "&displayCustomUOMWindow=true";
			userSettings.setDirty(true); //force a putUserSettings

		}

		//twistie status
		OrgSetup orgSetup = userPreferences.getOrgSetup();
		if(orgSetup!=null) {
			temp = request.getParameter("loadProfilesDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.systemData_LOADPROFILES_displayStyle, temp);
			}

			temp = request.getParameter("systemCurvesDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.systemData_SYSTEMCURVE_displayStyle, temp);
			}
		}

		//system curves
		doSystemCurves();
		doSystemCurveSetAtCheckboxes(oc);

		//load profiles...
		// get life cycle cost
		LifeCycleCost lcc = oc.getLifeCycleCost();
		if (lcc == null) {
			// create new life cycle cost if not yet created
			lcc = new LifeCycleCost(oc.getFluidDensity());
			lcc.initializeLoadProfiles(oc.getFlowReqd(), 5);
			lcc.setUserSettings(oc.getUserSettings());
		}

		// retrieve life cycle cost settings
		String pumpLife = request.getParameter("lifeExpectedPump");
		String flowSetting = request.getParameter("flowCriteriaLCC");
		String speedSetting = request.getParameter("speedCriteriaLCC");

		String operationSetting = request.getParameter("timeCriteriaLCC");
		if (operationSetting !=  null && operationSetting.length() > 0) {
			if (operationSetting.equals("percentOfYear")) {
				lcc.setTimeCriteriaLCC(LifeCycleCost.PERCENT);
			} else {
				lcc.setTimeCriteriaLCC(LifeCycleCost.REGULAR_UNIT);
			}
		}

		// set life cycle cost settings
		if (pumpLife != null && pumpLife.length() > 0) {
			lcc.setLifeExpectedPump(lcc.getUserSettings().getDoubleValue(pumpLife));
		}

		for (int i = 1; i <= 5; i++) {
			int currentIndex = i-1;
			LifeCycleCostLoadProfile profile = lcc.getLoadProfiles().get(currentIndex);

			if (flowSetting !=  null && flowSetting.length() > 0) {
				if (flowSetting.equals("percent")) {
					profile.setFlowCriteriaLCC(LifeCycleCostLoadProfile.PERCENT);
				} else {
					profile.setFlowCriteriaLCC(LifeCycleCostLoadProfile.REGULAR_UNIT);
				}
			}

			if (speedSetting !=  null && speedSetting.length() > 0) {
				if (speedSetting.equals("Variable")) {
					profile.setVariableSpeed(true);
				} else {
					profile.setVariableSpeed(false);
				}
			}

			if (operationSetting !=  null && operationSetting.length() > 0) {
				if (operationSetting.equals("percentOfYear")) {
					profile.setTimeCriteriaLCC(LifeCycleCostLoadProfile.PERCENT);
				} else {
					profile.setTimeCriteriaLCC(LifeCycleCostLoadProfile.REGULAR_UNIT);
				}
			}

			// set profile values
			String flowLoadProfileDirty = request.getParameter("flowLoadProfile" + i + "Dirty");
			if (flowLoadProfileDirty != null && flowLoadProfileDirty.length() > 0) {
				String flow = request.getParameter("flowLoadProfile" + i);
				if (flow != null && flow.length() > 0) {
					profile.setValue(LifeCycleCostLoadProfile.FLOW_USER, flow);
					}
			}
			String timeLoadProfileDirty = request.getParameter("timeLoadProfile" + i + "Dirty");
			if(timeLoadProfileDirty != null && timeLoadProfileDirty.length() > 0) {
				String time = request.getParameter("timeLoadProfile" + i);
				if (time != null && time.length() > 0) {
					profile.setValue(LifeCycleCostLoadProfile.TIME_USER, time);
				}
			}

			String energyCost = request.getParameter("energyCostLoadProfile" + i);
			if (energyCost != null && energyCost.length() > 0) {
				// IDD#6690 changed to currency
				profile.setValue(LifeCycleCostLoadProfile.ENERGY_COST, energyCost);
			}
			String enabled = request.getParameter("loadProfile" + i + "Enabled");
			if (enabled != null && enabled.length() > 0) {
				profile.setEnabledAndResetCalculatedValues(true);
			} else {
				profile.setEnabledAndResetCalculatedValues(false);
			}
			String etaMotor = request.getParameter("etaMotorLoadProfile" + i);
			if (etaMotor != null && etaMotor.length() > 0) {
				profile.setValue(LifeCycleCostLoadProfile.MOTOR_EFFICIENCY, etaMotor);
			}
			String etaDrive = request.getParameter("etaDriveLoadProfile" + i);
			if (etaDrive != null && etaDrive.length() > 0) {
				profile.setValue(LifeCycleCostLoadProfile.DRIVE_EFFICIENCY, etaDrive);
			}
			String systemCurve = request.getParameter("systemCurveLoadProfile" + i);
			if (systemCurve != null && systemCurve.length() > 0) {
				profile.setSystemCurveNumber(Integer.parseInt(systemCurve));
			}
		}

		// set life cycle costs on operating conditions
		oc.setLifeCycleCost(lcc);
	}

	/**
	 * performs the processing for the COS page
	 */
	void processCOS() {
		OperatingConditions oc = userPreferences.getOperatingConditions();
		String temp = "";

		do {  //not a loop, just a way to escape this code block once a popup has been found

			//check for a popup window request
			temp = request.getParameter("DisplayCustomUOMWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayCustomUOMWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayLiquidPropertiesWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayLiquidPropertiesWindow=true";
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayNPSHAvailableWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayNPSHAvailableWindow=true";
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayMultipleConditionsWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayMultipleConditionsWindow=true";
				break;
			}
		} while(false);  //not a loop, just a way to escape this code block once a popup has been found

		//twistie status
		OrgSetup orgSetup = userPreferences.getOrgSetup();
		if(orgSetup!=null) {
			temp = request.getParameter("advancedOperatingConditionsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.cos_ADVANCEDOPCONDS_displayStyle, temp);
			}
			temp = request.getParameter("basicOperatingConditionsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.cos_BASICOPCONDS_displayStyle, temp);
			}
			temp = request.getParameter("headerInfoDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.cos_HEADERINFO_displayStyle, temp);
			}
			temp = request.getParameter("selectionConstraintsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.cos_SELECTIONCONSTRAINTS_displayStyle, temp);
			}
			temp = request.getParameter("systemCurveDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.cos_SYSTEMCURVE_displayStyle, temp);
			}
			temp = request.getParameter("productLineOptionsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.cos_PRODLINEOPTIONS_displayStyle, temp);
			}
		}

		readHeaderInfo();

		// ########## the following are fields not required by KSB ##########
		temp = request.getParameter(OperatingConditions.CONSTRUCTION_SPEC);
		if(temp != null) {
			oc.setValue(OperatingConditions.CONSTRUCTION_SPEC, temp);
		}
		temp = request.getParameter(OperatingConditions.VISCOSITY_CORRECTION_SPEC);
		if(temp != null) {
			oc.setValue(OperatingConditions.VISCOSITY_CORRECTION_SPEC, temp);
		}
		temp = request.getParameter(OperatingConditions.DRIVER_DESIGN);
		if(temp != null) {
			oc.setValue(OperatingConditions.DRIVER_DESIGN, temp);
		}
		temp = request.getParameter(OperatingConditions.PHASE);
		if(temp != null) {
			oc.setValue(OperatingConditions.PHASE, temp);
		}
		temp = request.getParameter(OperatingConditions.HEAD_RISE_MINIMUM);
		if(temp != null) {
			oc.setValue(OperatingConditions.HEAD_RISE_MINIMUM, temp);
		}
		temp = request.getParameter("headRiseMaxUserDirty");
		if(temp != null && temp.equals("true")) {
			oc.setValue(OperatingConditions.HEAD_RISE_MAX_USER, request.getParameter("headRiseMaxUser"));
		}
		/*
		 * The unit choice for HEAD_RATED will override the unit choice for HEAD_SHUTOFF_MAX_USER
		 */
		temp = request.getParameter("headShutoffMaxUserDirty");
		if(temp != null && temp.equals("true")) {
			oc.setValue(OperatingConditions.HEAD_SHUTOFF_MAX_USER, request.getParameter("headShutoffMaxUser"), Integer.parseInt(request.getParameter("headShutoffMaxUserUnit")));
		}
		temp = request.getParameter(OperatingConditions.HYDRAULIC_SELECTION_SPEC);
		if(temp != null) {
			oc.setValue(OperatingConditions.HYDRAULIC_SELECTION_SPEC, temp);
		}
		temp = request.getParameter(OperatingConditions.MARGIN_OVER_SPEC);
		if(temp != null) {
			oc.setValue(OperatingConditions.MARGIN_OVER_SPEC, temp);
		}
		temp = request.getParameter(OperatingConditions.MATERIAL_MIN);
		if(temp != null) {
			oc.setValue(OperatingConditions.MATERIAL_MIN, temp);
		}
		temp = request.getParameter(OperatingConditions.NON_DROOP_CURVE);
		if(temp != null) {
			oc.setValue(OperatingConditions.NON_DROOP_CURVE, temp);
		} else {
			oc.setValue(OperatingConditions.NON_DROOP_CURVE, "false");
		}
		/*
		 * The unit choice for NPSH_AVAILABLE will override the unit choice for NPSH_MARGIN
		 */
		temp = request.getParameter(OperatingConditions.NPSH_MARGIN + "Dirty");
		if(temp != null && temp.equals("true")) {
			//the custom Blackmer COS page uses a single unit dropdown for both the NPSH margin and NPSH available
			String val = request.getParameter("singleNPSHUnit");
			if(val != null && val.equals("true")) {
				oc.setValue(OperatingConditions.NPSH_MARGIN, request.getParameter(OperatingConditions.NPSH_MARGIN), Integer.parseInt(request.getParameter(OperatingConditions.NPSH_AVAILABLE + "Unit")));
			} else {
				oc.setValue(OperatingConditions.NPSH_MARGIN, request.getParameter(OperatingConditions.NPSH_MARGIN), Integer.parseInt(request.getParameter(OperatingConditions.NPSH_MARGIN + "Unit")));
			}
		}
		temp = request.getParameter(OperatingConditions.SERVICE_FACTOR);
		if(temp != null) {
			try {
				oc.setServiceFactorUser(Double.parseDouble(temp));
			}
			catch (NumberFormatException ex) {
				ex.printStackTrace();
			}
		}
		temp = request.getParameter(OperatingConditions.USE_SERVICE_FACTOR);
		if(temp != null) {
			oc.setValue(OperatingConditions.USE_SERVICE_FACTOR, temp);
		} else {
			oc.setValue(OperatingConditions.USE_SERVICE_FACTOR, "false");
		}
		temp = request.getParameter(OperatingConditions.SUCTION_SPECIFIC_SPEED);
		if(temp != null) {
			oc.setValue(OperatingConditions.SUCTION_SPECIFIC_SPEED, temp, Integer.parseInt(request.getParameter(OperatingConditions.SUCTION_SPECIFIC_SPEED + "Unit")));
		}

		temp = request.getParameter(OperatingConditions.SPECIFIC_SPEED);
		if(temp != null) {
			// use same unit as suction_specific_speed
			oc.setValue(OperatingConditions.SPECIFIC_SPEED, temp, Integer.parseInt(request.getParameter(OperatingConditions.SUCTION_SPECIFIC_SPEED + "Unit")));
		}

		// ########## end of fields not required by KSB ##########

		temp = request.getParameter(OperatingConditions.DRIVER_SIZING_SPEC);
		if(temp != null) {
			oc.setValue(OperatingConditions.DRIVER_SIZING_SPEC, temp);
		}

		/**
		 * HEAD_RATED, VISCOSITY_RATED, and NPSH_AVAILABLE must be read and set
		 * in the operatingConditions after the
		 * readFluidDensityRatedAndUpdateRelatedMeasureGroups() method.
		 *
		 */
		readFluidDensityRatedAndUpdateRelatedMeasureGroups(oc);

		// retrieve user input for fluid density max
		if("true".equals(request.getParameter(OperatingConditions.SG_MAX + "Dirty"))) {
			String densityMax = request.getParameter(OperatingConditions.SG_MAX);
			// 0.0 is an invalid value so ignore.
			if (oc.getUserSettings().getDoubleValue(densityMax) > 0.0) {
				oc.setValue(OperatingConditions.SG_MAX, densityMax, Integer.parseInt(request.getParameter(OperatingConditions.FLUID_DENSITY + "Unit")));
			}
		}

		// get engine values for fluid density rated/max
		double densityRatedEngine = oc.getFluidDensity();
		double densityMaxEngine = oc.getSGMax();

		// get density restrictions from org-setup.xml, bypass validation if values do not exist
		double densityMinAllowedUser = 0;
		double densityMaxAllowedUser = 0;
		boolean densityValidationRequired = true;
		try {
			densityMinAllowedUser = Double.parseDouble(userPreferences.getOrgSetup().getValue(OrgSetup.DENSITY_MIN_ALLOWED_USER));
			densityMaxAllowedUser = Double.parseDouble(userPreferences.getOrgSetup().getValue(OrgSetup.DENSITY_MAX_ALLOWED_USER));
		} catch (NumberFormatException e) {
			densityValidationRequired = false;
		}

		// validate that fluid density, fluid density max are within limits of organization
		if (densityValidationRequired) {
			if (densityRatedEngine < densityMinAllowedUser || densityRatedEngine > densityMaxAllowedUser ||
				densityMaxEngine < densityMinAllowedUser || densityMaxEngine > densityMaxAllowedUser) {
				// density validation failed, set in session to notify COS page
				dao.setDensityValidationFailed(true);

				// redirect back to COS page
				String targetConditionsOfService = targetPath + ScreenNames.CONDITIONS_OF_SERVICE_URL;
				this.targetPage = targetConditionsOfService;
			} else {
				// density validation passed, set in session to notify COS page
				dao.setDensityValidationFailed(false);
			}
		}

		//system curves... Required by KSB's custom conditionsOfService.xsl
		boolean evaluateSystemCurves = Boolean.valueOf(request.getParameter("evaluateSystemCurves"));

		//IDD#6860: the systemCurve "set at" checkboxes MUST BE READ BEFORE the flow and head are read/set
		//this is because the "set at" checkboxes determine whether or not the cos head and flow should update the systemCurve head and flow
		if(evaluateSystemCurves) {
			doSystemCurveSetAtCheckboxes(oc);
		}

		//IDD#6860: flow must be read after the system curve checkboxes
		if(request.getParameter(OperatingConditions.FLOW_RATED + "Dirty").equals("true")) {
			int flowRatedUnit = HttpParamUtils.getIntParamSafely(request, OperatingConditions.FLOW_RATED + "Unit", -1);
			oc.setValue(OperatingConditions.FLOW_RATED, request.getParameter(OperatingConditions.FLOW_RATED), flowRatedUnit);
		}
		temp = request.getParameter(OperatingConditions.FREQUENCY);
		if(temp != null) {
			oc.setValue(OperatingConditions.FREQUENCY, temp);
		}
		/*
		 * The unit choice for HEAD_RATED will override the unit choice for HEAD_SHUTOFF_MAX_USER
		 *
		 * IDD#6860: head must be read after the system curve checkboxes
		 */
		if(request.getParameter(OperatingConditions.HEAD_RATED + "Dirty").equals("true")) {
			int headRatedUnit = HttpParamUtils.getIntParamSafely(request, OperatingConditions.HEAD_RATED + "Unit", -1);
			oc.setValue(OperatingConditions.HEAD_RATED, request.getParameter(OperatingConditions.HEAD_RATED), headRatedUnit);
		}
		temp = request.getParameter(OperatingConditions.LIQUID_DESCRIPTION);
		if(temp != null) {
			oc.setValue(OperatingConditions.LIQUID_DESCRIPTION, temp);
		}
		temp = request.getParameter(OperatingConditions.LIQUID_TYPE);
		if(temp != null) {
			oc.setValue(OperatingConditions.LIQUID_TYPE, temp);
		}
		/*
		 * The unit choice for NPSH_AVAILABLE will override the unit choice for NPSH_MARGIN
		 */
		if("true".equals(request.getParameter(OperatingConditions.NPSH_AVAILABLE + "Dirty"))) {
			oc.setValue(OperatingConditions.NPSH_AVAILABLE, request.getParameter(OperatingConditions.NPSH_AVAILABLE), Integer.parseInt(request.getParameter(OperatingConditions.NPSH_AVAILABLE + "Unit")));
		}
		if("true".equals(request.getParameter(OperatingConditions.PRESSURE_SUCTION_RATED + "Dirty"))) {
			oc.setValue(OperatingConditions.PRESSURE_SUCTION_RATED, request.getParameter(OperatingConditions.PRESSURE_SUCTION_RATED), Integer.parseInt(request.getParameter(OperatingConditions.PRESSURE_MAX_SUCTION + "Unit")));
		}
		if("true".equals(request.getParameter(OperatingConditions.PRESSURE_MAX_SUCTION + "Dirty"))) {
			oc.setValue(OperatingConditions.PRESSURE_MAX_SUCTION, request.getParameter(OperatingConditions.PRESSURE_MAX_SUCTION), Integer.parseInt(request.getParameter(OperatingConditions.PRESSURE_MAX_SUCTION + "Unit")));
		}

		// process product line options if product line selected exists
		String productLineIDSupplier = userPreferences.getSelectedProductLineIDSupplier();
		if (productLineIDSupplier != null) {
			ProductLineModel productLineModel = productLineWeb.getDetailsBySupplierID(productLineIDSupplier, userPreferences);
			if(productLineModel != null) {
				processProductLinePerformanceOptions(oc, productLineModel);
			} else {
				oc.setProductLineExists(false);
			}
		}

		if("true".equals(request.getParameter(OperatingConditions.SOLIDS_DIAMETER_MAX + "Dirty"))) {
			oc.setValue(OperatingConditions.SOLIDS_DIAMETER_MAX, request.getParameter(OperatingConditions.SOLIDS_DIAMETER_MAX), Integer.parseInt(request.getParameter(OperatingConditions.SOLIDS_DIAMETER_MAX + "Unit")));
		}

		String solidsConcentrationByVolumeDirty = request.getParameter(OperatingConditions.SOLIDS_CONCENTRATION_BY_VOLUME + "Dirty");
		if(solidsConcentrationByVolumeDirty != null && solidsConcentrationByVolumeDirty.equals("true")) {
			oc.setValue(OperatingConditions.SOLIDS_CONCENTRATION_BY_VOLUME, request.getParameter(OperatingConditions.SOLIDS_CONCENTRATION_BY_VOLUME));
		}

		String solidsHardnessType = request.getParameter("solidsHardnessType");
		if(solidsHardnessType != null && solidsHardnessType.length() > 0) {
			oc.setSolidsHardnessType(solidsHardnessType);
		} else {
			oc.setSolidsHardnessType (SolidsHardnessType.NOT_APPLICABLE);
		}

		temp = request.getParameter(OperatingConditions.SHEAR_SENSITIVE_LIQUID);
		if(temp != null) {
			oc.setValue(OperatingConditions.SHEAR_SENSITIVE_LIQUID, temp);
		} else {
			oc.setValue(OperatingConditions.SHEAR_SENSITIVE_LIQUID, "false");
		}

		if("true".equals(request.getParameter(OperatingConditions.TEMPERATURE_MAX + "Dirty"))) {
			oc.setValue(OperatingConditions.TEMPERATURE_MAX, request.getParameter(OperatingConditions.TEMPERATURE_MAX), Integer.parseInt(request.getParameter(OperatingConditions.TEMPERATURE_MAX + "Unit")));
		}

		if ("true".equals(request.getParameter(OperatingConditions.VISCOSITY_RATED + "Dirty"))) {
			String viscosityRated = request.getParameter(OperatingConditions.VISCOSITY_RATED);
			if (oc.getUserSettings().getDoubleValue(viscosityRated) > 0.0) {
				oc.setValue(OperatingConditions.VISCOSITY_RATED, viscosityRated, Integer.parseInt(request.getParameter(OperatingConditions.VISCOSITY_RATED + "Unit")));
			}
		}

		temp = request.getParameter(OperatingConditions.PRESSURE_VAPOR_RATED + "Dirty");
		if("true".equals(temp)) {
			oc.setValue(OperatingConditions.PRESSURE_VAPOR_RATED, request.getParameter(OperatingConditions.PRESSURE_VAPOR_RATED), Integer.parseInt(request.getParameter(OperatingConditions.PRESSURE_VAPOR_RATED + "Unit")));
		}

		temp = request.getParameter(OperatingConditions.FLOW_FACTOR_USER + "Dirty");
		if("true".equals(temp)) {
			oc.setValue(OperatingConditions.FLOW_FACTOR_USER, request.getParameter(OperatingConditions.FLOW_FACTOR_USER));
		}

		temp = request.getParameter(OperatingConditions.HEAD_FACTOR_USER + "Dirty");
		if("true".equals(temp)) {
			oc.setValue(OperatingConditions.HEAD_FACTOR_USER, request.getParameter(OperatingConditions.HEAD_FACTOR_USER));
		}

		temp = request.getParameter(OperatingConditions.ETA_FACTOR_USER + "Dirty");
		if("true".equals(temp)) {
			oc.setValue(OperatingConditions.ETA_FACTOR_USER, request.getParameter(OperatingConditions.ETA_FACTOR_USER));
		}

		temp = request.getParameter(OperatingConditions.NPSH_FACTOR_USER + "Dirty");
		if("true".equals(temp)) {
			oc.setValue(OperatingConditions.NPSH_FACTOR_USER, request.getParameter(OperatingConditions.NPSH_FACTOR_USER));
		}

		temp = request.getParameter(OperatingConditions.POWER_LOSS_USER + "Dirty");
		if("true".equals(temp)) {
			oc.setValue(OperatingConditions.POWER_LOSS_USER, request.getParameter(OperatingConditions.POWER_LOSS_USER));
		}

		temp = request.getParameter(OperatingConditions.TORQUE_LOSS_USER + "Dirty");
		if("true".equals(temp)) {
			oc.setValue(OperatingConditions.TORQUE_LOSS_USER, request.getParameter(OperatingConditions.TORQUE_LOSS_USER));
		}

		String conditionsOfServiceExistFlag = request.getParameter("ConditionsOfServiceExistFlag");
		if(conditionsOfServiceExistFlag != null && conditionsOfServiceExistFlag.length() > 0) {
			userPreferences.setConditionsOfServiceExist(stringToBoolean(conditionsOfServiceExistFlag));
		}

		/**
		 * IDD#8821: always set the setSearchResultsRecalcNeeded to true for the COS page,
		 * regardless of the SearchResultsDirtyFlag because the XSL is not setting it correctly.
		 */
		userPreferences.setSearchResultsRecalcNeeded(true);

		String savedFlag = request.getParameter("IsSavedFlag");
		if(savedFlag != null && savedFlag.length() > 0) {
			userPreferences.setSaved(stringToBoolean(savedFlag));
		}

		String searchCriteriaUser = request.getParameter("SearchCriteriaUser");
		if(searchCriteriaUser != null && searchCriteriaUser.length() > 0) {
			oc.setSearchCriteria(Integer.parseInt(searchCriteriaUser));
		} else {
			oc.setSearchCriteria (SearchCriteria.POLES_ALL);
		}

		String PolesSetSearchUser = request.getParameter("PolesSetSearchUser");
		if(PolesSetSearchUser != null && PolesSetSearchUser.length() > 0) {
			oc.setPolesSetSearchUser(Integer.parseInt(PolesSetSearchUser));
		}

		String PolesLimitMinSearchUser = request.getParameter("PolesLimitMinSearchUser");
		if(PolesLimitMinSearchUser != null && PolesLimitMinSearchUser.length() > 0) {
			oc.setPolesMinSearchUser(Integer.parseInt(PolesLimitMinSearchUser));
		}

		String PolesLimitMaxSearchUser = request.getParameter("PolesLimitMaxSearchUser");
		if(PolesLimitMaxSearchUser != null && PolesLimitMaxSearchUser.length() > 0) {
			oc.setPolesMaxSearchUser(Integer.parseInt(PolesLimitMaxSearchUser));
		}

		String SpeedSetSearchUser = request.getParameter("SpeedSetSearchUser");
		if(SpeedSetSearchUser != null && SpeedSetSearchUser.length() > 0) {
			oc.setSpeedSetSearchUser(Integer.parseInt(SpeedSetSearchUser));
		}

		String speedLimitMaxSearchUser = request.getParameter("speedLimitMaxSearchUser");
		if (StringUtils.isDefined(speedLimitMaxSearchUser)) {
			oc.setSpeedLimitMaxSearchUser(Integer.parseInt(speedLimitMaxSearchUser));
		}

		String speedLimitMinSearchUser = request.getParameter("speedLimitMinSearchUser");
		if (StringUtils.isDefined(speedLimitMinSearchUser)) {
			oc.setSpeedLimitMinSearchUser(Integer.parseInt(speedLimitMinSearchUser));
		}

		if(evaluateSystemCurves) {
			doSystemCurves();
		}

		// Ensure that all selected productLines are still compatible after processing new COS
		TreeMap productLinesSelectedList = userPreferences.getProductLinesSelectedList();
		Set keySet = productLinesSelectedList.keySet();
		Iterator iterKeySet = keySet.iterator();
		String idSupplier = null;
		ProductLineModel model = null;
		LinkedList removeList = new LinkedList();

		//check for incompatibles
		while (iterKeySet.hasNext()) {
			Integer index = (Integer)iterKeySet.next();
			idSupplier = String.valueOf(productLinesSelectedList.get(index));
			model = productLineWeb.getDetailsBySupplierID(idSupplier, userPreferences);

			if(model == null || !model.isCompatible()) {
				removeList.add(index);

				//if this is the currently selected productLine then clear it
				if(idSupplier.equals(userPreferences.getSelectedProductLineIDSupplier())) {
					userPreferences.setSelectedProductLineIDSupplier(null);
					oc.setProductLineExists(false);
				}
			}
		}

		//remove them (cannot be done in above list due to ConcurrentModificationException, IDD#5019)
		iterKeySet = null;
		Iterator removeIterator = removeList.iterator();
		while(removeIterator.hasNext()) {
			Integer index = (Integer)removeIterator.next();
			productLinesSelectedList.remove(index);
		}


		/*
		 * some unit groups have two dropdowns, here we set the units using the primary dropdown
		 */
		//the head units dropdown is present for head rated and headShutoffMaxUser
		temp = request.getParameter(OperatingConditions.HEAD_RATED + "Unit");
		if(temp!=null) {
			int uom = Integer.parseInt(temp);
			userSettings.getUnitOfMeasureSettings().setSelectedUnitOfMeasure(Measure.HEAD,uom);
		}
		//the NPSH units dropdown is present for NPSH available and NPSH margin
		temp = request.getParameter(OperatingConditions.NPSH_AVAILABLE + "Unit");
		if(temp!=null) {
			int uom = Integer.parseInt(request.getParameter(OperatingConditions.NPSH_AVAILABLE + "Unit"));
			userSettings.getUnitOfMeasureSettings().setSelectedUnitOfMeasure(Measure.NPSH,uom);
		}

		/*
		 * Check errors during navigation
		 */
		if(checkForITOCosError3(oc,alert)) {
			String targetConditionsOfService = targetPath + ScreenNames.CONDITIONS_OF_SERVICE_URL;
			this.targetPage = targetConditionsOfService;
		}

		//DEBUG
		//System.out.println("PolesSetSearchUser = " + PolesSetSearchUser);
		//System.out.println("PolesLimitMinSearchUser = " + PolesLimitMinSearchUser);
		//System.out.println("PolesLimitMaxSearchUser = " + PolesLimitMaxSearchUser);
		//System.out.println("PolesSpeedSetSearchUser = " + SpeedSetSearchUser);
	}

	/**
	 * Read the system curve "set at" checkboxes from the request and set into {@link OperatingConditions}
	 * @param oc
	 */
	private void doSystemCurveSetAtCheckboxes(OperatingConditions oc) {
		String temp;
		temp = request.getParameter("headSystemSetUser");
		if(temp!=null) {
			oc.setHeadSystemSetUser(true);
		} else {
			oc.setHeadSystemSetUser(false);
		}

		temp = request.getParameter("flowSystemSetUser");
		if(temp!=null) {
			oc.setFlowSystemSetUser(true);
		} else {
			oc.setFlowSystemSetUser(false);
		}
	}

	private List processSelectedProductLineSupplierIds(String selectedProductLineIDSupplier) {
		List list = new ArrayList();
		StringTokenizer st = new StringTokenizer(selectedProductLineIDSupplier, ";");
		while(st.hasMoreTokens()) {
			String id = st.nextToken();
			list.add(id);
		}
		return list;
	}

	/**
	 * performs the processing for the ProductLines page
	 */
	void processProductLines() {
		OperatingConditions oc = userPreferences.getOperatingConditions();

		String temp = "";

		//check for a popup window request
		temp = request.getParameter("DisplayCustomUOMWindow");
		if(temp != null && temp.equals("true")) {
			targetPage += "&displayCustomUOMWindow=true";
			userSettings.setDirty(true); //force a putUserSettings
		}

		//twistie status
		OrgSetup orgSetup = userPreferences.getOrgSetup();
		if(orgSetup!=null) {
			temp = request.getParameter("productLineFiltersDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.prodLines_PRODUCTLINEFILTERS_displayStyle, temp);
			}
		}

		TreeMap<Integer, String> productLinesSelectedList = new TreeMap<Integer, String>();
		Enumeration enumParamNames = request.getParameterNames();
		String parameterNamePrefixPL = "PL";
		String parameterNamePrefixMOC = "MOC";
		String selectedProductLineIDSupplier = "";
		if(enumParamNames != null) {
			while(enumParamNames.hasMoreElements()) {

				String parameterName = (String)enumParamNames.nextElement();
				if(parameterName!= null && parameterName.startsWith(parameterNamePrefixPL)) {
					selectedProductLineIDSupplier = request.getParameter(parameterName);
					int sortOrder = 10000;  //dont want this to overwrite a true productline entry if parseInt fails
					try {
						sortOrder = Integer.parseInt(parameterName.substring(parameterNamePrefixPL.length(),parameterName.length()).trim());
					} catch(NumberFormatException e) {
						System.err.println("ERROR: retrieveal of productline sort order from request object for org "+userPreferences.getOrgID());
						e.printStackTrace();
					}

					List supplierIds = processSelectedProductLineSupplierIds(selectedProductLineIDSupplier);
					Iterator iterator = supplierIds.iterator();
					int cnt = 0;
					while(iterator.hasNext()) {
						String supplierId = (String) iterator.next();

						if(supplierId != null) {
							cnt++;
							//Integer selectedIndex = new Integer(parameterName.substring(parameterNamePrefixPL.length()));
							//Integer selectedIndex = new Integer(cnt);
							Integer selectedIndex = Integer.valueOf((sortOrder*100)+cnt); // allow space for the productLineAutoPick(s)
							if(!productLinesSelectedList.containsValue(supplierId)) {
								productLinesSelectedList.put(selectedIndex, supplierId);
							}
							String mocID = request.getParameter("MOC" + supplierId);
							if(mocID != null) {
								if(!mocID.equals("-1")) {
									//-1 is the none option
									oc.setMaterialOfConstructionRequested(supplierId, mocID);
								}
							}
						}
					}
				} else if(parameterName!= null && parameterName.startsWith(parameterNamePrefixMOC)) {
					String parameterValue = request.getParameter(parameterName);
					if(parameterValue != null && !parameterValue.equals("-1")) {
						//-1 is the none option
						String selectedProdLineIDSupplier = parameterName.substring(parameterNamePrefixMOC.length());
						oc.setMaterialOfConstructionRequested(selectedProdLineIDSupplier, parameterValue);
					}
				}
			}
		}

		userPreferences.setProductLinesSelectedList(productLinesSelectedList);

		if (userPreferences.getSelectedPumpDetails() != null) {
			if (!productLinesSelectedList.containsValue(userPreferences.getSelectedPumpDetails().getProductLineIDSupplier())) {
				userPreferences.setSelectedPumpDetails(null);
			}
		}

		// if only one product line selected, set selected productLineIDSupplier in user prefs
		if (productLinesSelectedList.size() == 1) {
			userPreferences.setSelectedProductLineIDSupplier(selectedProductLineIDSupplier);
		}

		//set oc
		String tempParam = null;
		tempParam = request.getParameter(Attributes.CONSTRUCTION_SPEC);
		if(tempParam != null) {
			oc.setValue(Attributes.CONSTRUCTION_SPEC, tempParam);
		}
		tempParam = request.getParameter(Attributes.INDUSTRY);
		if(tempParam != null) {
			oc.setValue(Attributes.INDUSTRY, tempParam);
		}
		tempParam = request.getParameter(Attributes.MATERIAL_MIN);
		if(tempParam != null) {
			oc.setValue(Attributes.MATERIAL_MIN, tempParam);
		}
		tempParam = request.getParameter(Attributes.ORIENTATION);
		if(tempParam != null) {
			oc.setValue(Attributes.ORIENTATION, tempParam);
		}
		tempParam = request.getParameter(Attributes.PRODUCT_CLASSIFICATION);
		if(tempParam != null) {
			oc.setValue(Attributes.PRODUCT_CLASSIFICATION, tempParam);
		}
		tempParam = request.getParameter(Attributes.LIQUID_TYPE);
		if(tempParam != null) {
			oc.setValue(Attributes.LIQUID_TYPE, tempParam);
		}

		tempParam = request.getParameter(Attributes.FLOW_MAX_ALLOW + "Unit");
		if(tempParam != null) {
			userPreferences.setUnitOfMeasure(Attributes.FLOW_MAX_ALLOW, Integer.parseInt(tempParam));
		}
		tempParam = request.getParameter(Attributes.HEAD_MAX_ALLOW + "Unit");
		if(tempParam != null) {
			userPreferences.setUnitOfMeasure(Attributes.HEAD_MAX_ALLOW, Integer.parseInt(tempParam));
		}
		tempParam = request.getParameter(Attributes.PRESSURE_MAX_ALLOW_SUCTION + "Unit");
		if(tempParam != null) {
			userPreferences.setUnitOfMeasure(Attributes.PRESSURE_MAX_ALLOW_SUCTION, Integer.parseInt(tempParam));
		}
		tempParam = request.getParameter(Attributes.TEMPERATURE_MAX_ALLOW + "Unit");
		if(tempParam != null) {
			userPreferences.setUnitOfMeasure(Attributes.TEMPERATURE_MAX_ALLOW, Integer.parseInt(tempParam));
		}
		tempParam = request.getParameter(Attributes.VISCOSITY_MAX_ALLOW + "Unit");
		if(tempParam != null) {
			userPreferences.setUnitOfMeasure(Attributes.VISCOSITY_MAX_ALLOW, Integer.parseInt(tempParam));
		}
		tempParam = request.getParameter(Attributes.SOLIDS_DIAMETER_MAX_ALLOW + "Unit");
		if(tempParam != null) {
			userPreferences.setUnitOfMeasure(Attributes.SOLIDS_DIAMETER_MAX_ALLOW, Integer.parseInt(tempParam));
		}

		String productLinesSelectedFlag = request.getParameter("ProductLinesSelectedFlag");
		if(productLinesSelectedFlag != null && productLinesSelectedFlag.length() > 0) {
			userPreferences.setProductLinesSelected(stringToBoolean(productLinesSelectedFlag));
		}

		String searchResultsDirtyFlag = request.getParameter("SearchResultsDirtyFlag");
		if(searchResultsDirtyFlag != null && searchResultsDirtyFlag.length() > 0) {
			userPreferences.setSearchResultsRecalcNeeded(stringToBoolean(searchResultsDirtyFlag));
		}

		String savedFlag = request.getParameter("IsSavedFlag");
		if(savedFlag != null && savedFlag.length() > 0) {
			userPreferences.setSaved(stringToBoolean(savedFlag));
		}

		String productLineFilter = request.getParameter("ProductLineFilter");
		if(productLineFilter != null && productLineFilter.length() > 0) {
			userPreferences.setProductLineFilter(Integer.parseInt(productLineFilter));
		}
	}

	/**
	 * performs the processing for the ProductLineOptions page
	 */
	void processProductLineOptions() {

		String temp = "";

		//check for a popup window request
		temp = request.getParameter("DisplayCustomUOMWindow");
		if(temp != null && temp.equals("true")) {
			targetPage += "&displayCustomUOMWindow=true";
			userSettings.setDirty(true); //force a putUserSettings
		}

		// get operating conditions
		OperatingConditions oc = userPreferences.getOperatingConditions();

		// process product line options for each product line
		TreeMap productLinesSelectedList = userPreferences.getProductLinesSelectedList();
		Collection supplierIDList = productLinesSelectedList.values();
		Iterator iterator = supplierIDList.iterator();
		while (iterator.hasNext()) {
			String supplierID = String.valueOf(iterator.next());

			// process product line options for product line
			ProductLineModel productLineModel = productLineWeb.getDetailsBySupplierID(supplierID, userPreferences);
			if(productLineModel != null) {
				processProductLinePerformanceOptions(oc, productLineModel);
			}
		}

		String searchResultsDirtyFlag = request.getParameter("SearchResultsDirtyFlag");
		if(searchResultsDirtyFlag != null && searchResultsDirtyFlag.length() > 0) {
			userPreferences.setSearchResultsRecalcNeeded(stringToBoolean(searchResultsDirtyFlag));
		}
	}

	/**
	 * performs the processing for the PumpSizeList page
	 */
	void processPumpSizeList() {

		String temp = "";
		boolean pumpSizeSelected = false;

		//check for a popup window request
		temp = request.getParameter("DisplayCustomUOMWindow");
		if(temp != null && temp.equals("true")) {
			targetPage += "&displayCustomUOMWindow=true";
			userSettings.setDirty(true); //force a putUserSettings

		}

		String requestTemp = null;
		if((isKSBUser && !isIEQAdvancedUser) || isIEQBasicUser) {
			requestTemp = request.getParameter("ProductLine");
			// ProductLine field is not present in the form
			if(requestTemp != null) {
				//Long selectedProductLineID = new Long(Long.parseLong(requestTemp));
				//productLinesSelectedList.put(selectedIndex, selectedProductLineID);
				//userPreferences.setProductLinesSelectedList(productLinesSelectedList);
			}
		}

		// Note that the code for pump size list in app/unit is NOT the same as that in NavigationFlags.jsp

		String conditionsOfServiceExistFlag = request.getParameter("ConditionsOfServiceExistFlag");
		if(conditionsOfServiceExistFlag != null && conditionsOfServiceExistFlag.length() > 0) {
			userPreferences.setConditionsOfServiceExist(stringToBoolean(conditionsOfServiceExistFlag));
		}

		String savedFlag = request.getParameter("IsSavedFlag");
		if(savedFlag != null && savedFlag.length() > 0) {
			userPreferences.setSaved(stringToBoolean(savedFlag));
		}

		String searchResultsDirtyFlag = request.getParameter("SearchResultsDirtyFlag");
		if(searchResultsDirtyFlag != null && searchResultsDirtyFlag.length() > 0) {
			userPreferences.setSearchResultsRecalcNeeded(stringToBoolean(searchResultsDirtyFlag));
		}

		String selectedProductLineIDSupplier = request.getParameter("SelectedProductLineIDSupplier");
		if(selectedProductLineIDSupplier != null && selectedProductLineIDSupplier.length() > 0) {
			userPreferences.setSelectedProductLineIDSupplier(selectedProductLineIDSupplier);
		}

		String selectedPumpID = request.getParameter("SelectedPumpIDSupplier");
		if(selectedPumpID != null && selectedPumpID.length() > 0) {
			userPreferences.setSelectedPumpIDSupplier(selectedPumpID);

			// Set pumpSizeSelected flag to indicate whether or not
			// the operating conditions should be reset. Don't want
			// to reset the operating conditions if the user has not
			// selected a pump size.
			pumpSizeSelected = true;
		}

		String selectionExistsFlag = request.getParameter("SelectionExistsFlag");
		if(selectionExistsFlag != null && selectionExistsFlag.length() > 0) {
			userPreferences.setSelectionExists(stringToBoolean(selectionExistsFlag));
		}


		if(pumpSizeSelected) {
			userPreferences.resetChartAxisGridControlsWithOrgSetupDefaults();

			String isPDPump = request.getParameter("isPDPump");
			if(isPDPump != null && isPDPump.equals("true")){
				userPreferences.resetOperatingConditionsForPDSizeList();
			} else {
				userPreferences.resetOperatingConditionsForSizeList(true);
			}
			OperatingConditions oc = userPreferences.getOperatingConditions();

			//first clear out the old userSelectedCompatiblePumps
			oc.clearPumpSetConditionsCollection();

			//clear out the minimizeTrimmedStages selections
			oc.clearUserMinimizeTrimStages();

			if(oc != null) {

				//reset the selected curveNumber to null, so it can be re-calc'd for the user's chosen speed
				oc.setCurveNumberSetItemSystem(null);

				//disable all ITO conditions
				oc.setEnabledTakeoff1(false);
				oc.setEnabledTakeoff2(false);

				/*
				String flowAtBEP = request.getParameter(Attributes.FLOW_AT_BEP);
				if(flowAtBEP != null && flowAtBEP.length() > 0) {
					oc.setFlowReqd(Double.parseDouble(flowAtBEP));
				}

				String headAtBEP = request.getParameter(Attributes.HEAD_AT_BEP);
				if(headAtBEP != null && headAtBEP.length() > 0) {
					oc.setHeadReqd(Double.parseDouble(headAtBEP));
				}
				*/

				requestTemp = request.getParameter(Attributes.FREQUENCY);
				if(requestTemp != null) {
					oc.setValue(OperatingConditions.FREQUENCY, requestTemp);
				}

				// set Speed
				String speed = request.getParameter("Speed");
				if (speed != null && speed.length() > 0) {
					//DEBUG
					//System.out.println("NavigationFlags.java: Speed = " + speed);
					String speedDisplayType = request.getParameter("SpeedDisplayType");
					if(speedDisplayType != null && speedDisplayType.equals("textbox")) {
						//in display units
						oc.setValue(OperatingConditions.SPEED_USER, speed);
					} else {
//						in system units
						oc.setSpeedUser(Double.parseDouble(speed));
					}

					//DEBUG
					//System.out.println("NavigationFlags.java: oc.getSpeedUser() = " + oc.getSpeedUser());
				}

				String viscosity = request.getParameter("Viscosity");
				if(viscosity != null && viscosity.length() > 0) {
					oc.setViscosityRated(Double.parseDouble(viscosity));
				}


				// set Stages
				String stages = request.getParameter("Stages");
				if (stages != null && stages.length() > 0) {
					//DEBUG
					//System.out.println("NavigationFlags.java: Stages = " + stages);

					oc.setStagesUser(Integer.parseInt(stages));

					//DEBUG
					//System.out.println("NavigationFlags.java: oc.getStagesUser() = " + oc.getStagesUser());
				}

				// set Diameter
				String solveVariant = request.getParameter("SolveVariant");
				if(solveVariant != null && solveVariant.length() > 0) {
					String paramName = "ImpellerDiameter";
					if(solveVariant.equals(PumpDetails.IMPELLER_SPEED_RATED)){
						paramName = "ImpellerSpeed";
					} else if(solveVariant.equals(PumpDetails.IMPELLER_WIDTH_RATED)){
						paramName = "ImpellerWidth";
					} else if(solveVariant.equals(PumpDetails.PROPELLER_PITCH_RATED)){
						paramName = "PropellerPitch";
					} else if (solveVariant.equals(PumpDetails.AIR_PRESSURE_RATED)) {
						paramName = "AirPressure";
					}
					String solveVariantValue = request.getParameter(paramName);

					if (solveVariantValue != null && solveVariantValue.length() > 0) {
						//DEBUG
						//System.out.println("NavigationFlags.java: Diameter = " + diameter);

							//diameter will always come in as a display value, not system value
							oc.setValue(solveVariant,solveVariantValue);

						//DEBUG
						//System.out.println("NavigationFlags.java: oc.getDiaSetItemUser() = " + oc.getDiaSetItemUser());
					}
				}

				//The check "pumpSizeSelected" above ensures it's a valid pump. This enables the flow/head calculation while leaving size list page
				oc.setDetailsPage(OperatingConditions.PUMP_DETAILS_FROM_SIZE_LIST);

				/*Set mixed stage info because a pump has been chosen*/

//				first clear out the old userSelectedCompatiblePumps
				oc.clearPumpSetConditionsCollection();

				// set alternate first stage pump ID if specified
				String altFirstStagePumpID = request.getParameter("AlternateFirstStagePumpID");
				if (altFirstStagePumpID != null && altFirstStagePumpID.length() > 0) {
					PumpSetConditions pump = new PumpSetConditionsImpl();
					pump.setPumpID(Integer.parseInt(altFirstStagePumpID));
					pump.setEnabled(true);
					oc.setPumpSetConditions(pump, CompatiblePumpSelected.ALTERNATE_FIRST_STAGE);
				}
			}
		}

		if(!pumpSizeSelected) {
			OperatingConditions oc = userPreferences.getOperatingConditions();

			if(oc != null) {
				String freq = request.getParameter(OperatingConditions.FREQUENCY);
				if(freq != null) {
					oc.setValue(OperatingConditions.FREQUENCY, freq);
				}
			}
		}
	}

	/**
	 * performs the processing for the SearchResults page
	 */
	void processSearchResults() {
		OperatingConditions oc = userPreferences.getOperatingConditions();
		String temp = "";

		do { //not a loop, just a way to escape this code block once a popup has been found

			//check for a popup window request
			temp = request.getParameter("DisplayCustomUOMWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayCustomUOMWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayAdvSortWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayAdvSortWindow=true";
				break;
			}

		}while(false); //not a loop, just a way to escape this code block once a popup has been found


		// go to page one if number of selections has changed
		String numSelectedChanged = request.getParameter("NumSelectedChanged");

		if(numSelectedChanged != null && numSelectedChanged.length() > 0) {
			if(numSelectedChanged.equals("true")) {
				// set to go to first page
				//session.setAttribute("thumbnailsPageReference", "1");
			}
		}

		// Get a list of pump ID's that have been selected for viewing thumbnail curves
		ArrayList thumbnailCurvePumpTempKeyList = new ArrayList();
		Iterator iterThumbnailCurvePumpTempKeys = null;
		TreeMap pumpDetailsTempKeyMap = dao.getPumpDetailsKeyMap();  //IDD#2132: provides "SR" name to pumpDetail key mappings
		Enumeration enumParamNames = request.getParameterNames();
		String parameterNamePrefix = "SR";

		//init the list with the temporary keys
		int checkCount = 0;
		while(enumParamNames.hasMoreElements()) {
			String parameterName = (String)enumParamNames.nextElement();

			if(parameterName.startsWith(parameterNamePrefix)) {
				checkCount++;

				String parameterValue = request.getParameter(parameterName);

				if(parameterValue != null) {
					String selectedPumpKey = String.valueOf(parameterValue);
					thumbnailCurvePumpTempKeyList.add(selectedPumpKey);
				}
			}
		}

		// Set the iterator from the list of temporary keys
		// if no checkboxes checked, select them all by adding all values of checkboxes
		// to pump list (using hidden fields)
		if(checkCount == 0) {

			//use all thumbnail curves
			iterThumbnailCurvePumpTempKeys = null;
			if(pumpDetailsTempKeyMap != null) {
				iterThumbnailCurvePumpTempKeys = pumpDetailsTempKeyMap.keySet().iterator();
			}

			// this session attribute is used in SearchResultsPage.java
			dao.setAllThumbnailsImplicitlySelected("true");
		} else {

			//use the selected thumbnail curves
			iterThumbnailCurvePumpTempKeys = thumbnailCurvePumpTempKeyList.iterator();

			// this session attribute is used in SearchResultsPage.java
			dao.setAllThumbnailsImplicitlySelected("false");
		}

		//Generate list of pump details objects that are to be viewed as thumbnail curves
		HashMap thumbnailCurvePumpDetailsList = new HashMap();
		HashMap pumpDetailsHash = dao.getPumpDetailsHash();
		if(pumpDetailsHash != null) {
			while(iterThumbnailCurvePumpTempKeys != null && iterThumbnailCurvePumpTempKeys.hasNext()) {
				String pumpTempKey = (String)iterThumbnailCurvePumpTempKeys.next();
				String pumpKey = String.valueOf(pumpDetailsTempKeyMap.get(pumpTempKey));
				PumpDetails pumpDetails = (PumpDetails)pumpDetailsHash.get(pumpKey);

				//set the temporary key, to be used in the OutputGraphServlet
				pumpDetails.setTempKey(pumpTempKey);

				//add this pumpDetails object to the thumbnailCurvePumpDetailsList
				thumbnailCurvePumpDetailsList.put(pumpKey, pumpDetails);
			}
		}
		userPreferences.setThumbnailCurvesSelectedList(thumbnailCurvePumpDetailsList);

		String npshRequiredUOM = request.getParameter(PumpDetails.NPSH_REQUIRED + "Unit");
		if(npshRequiredUOM != null) {
			userPreferences.setUnitOfMeasure(PumpDetails.NPSH_REQUIRED, Integer.parseInt(npshRequiredUOM));
		}

		String powerMaxRatedUOM = request.getParameter(PumpDetails.POWER_MAX_RATED + "Unit");
		if(powerMaxRatedUOM != null) {
			userPreferences.setUnitOfMeasure(PumpDetails.POWER_MAX_RATED, Integer.parseInt(powerMaxRatedUOM));
		}

		String searchResultsDirtyFlag = request.getParameter("SearchResultsDirtyFlag");
		if(searchResultsDirtyFlag != null && searchResultsDirtyFlag.length() > 0) {
			userPreferences.setSearchResultsRecalcNeeded(stringToBoolean(searchResultsDirtyFlag));
		}

		String selectionExistsFlag = request.getParameter("SelectionExistsFlag");
		if(selectionExistsFlag != null && selectionExistsFlag.length() > 0) {
			userPreferences.setSelectionExists(stringToBoolean(selectionExistsFlag));
		}

		String selectedProductLineIDSupplier = request.getParameter("SelectedProductLineIDSupplier");
		if(selectedProductLineIDSupplier != null && selectedProductLineIDSupplier.length() > 0 && !selectedProductLineIDSupplier.equals("-")) {
			userPreferences.setSelectedProductLineIDSupplier(selectedProductLineIDSupplier);
		}

		String selectedPumpIDSupplier = request.getParameter("SelectedPumpIDSupplier");
		if(selectedPumpIDSupplier != null && selectedPumpIDSupplier.length() > 0 && !selectedPumpIDSupplier.equals("-")) {
			userPreferences.setSelectedPumpIDSupplier( selectedPumpIDSupplier );

			userPreferences.resetOperatingConditionsForSearchResults();

			setMixedStageInfo(oc);

			userPreferences.resetChartAxisGridControlsWithOrgSetupDefaults();
		}

		String gearSelected = request.getParameter("SelectedGear");
		if(gearSelected != null && gearSelected.length() > 0) {
			oc.setGearSelected( gearSelected );
		}

		String vaneSelected = request.getParameter("SelectedVane");
		if(vaneSelected != null && vaneSelected.length() > 0) {
			oc.setVaneSelectedFromSearchPage( vaneSelected );
		}

		String selectedStages = request.getParameter("SelectedStages");
		if(selectedStages != null && selectedStages.length() > 0 && !selectedStages.equals("-")) {
			oc.setValue(OperatingConditions.STAGES_USER, selectedStages);
		}

		String isVariableSpeedStr = request.getParameter("VariableSpeed");
		if(isVariableSpeedStr != null && isVariableSpeedStr.length() > 0) {
			boolean isVariableSpeed = Boolean.valueOf(isVariableSpeedStr).booleanValue();

			if(isVariableSpeed) {
				oc.setSpeedCriteria(SpeedCriteria.VARIABLE);

				String selectedDiameter = request.getParameter("SelectedDiameter");
				if(selectedDiameter != null && selectedDiameter.length() > 0 && !selectedStages.equals("-")) {
					oc.setSpeedUser(OperatingConditions.SPEED_USER_NOT_CHECKED);
					try {
						oc.setDiaSetItemUser(Double.parseDouble(selectedDiameter));
					} catch (NumberFormatException e) {
						e.printStackTrace();
					}
				}
			} else {
				oc.setSpeedCriteria(SpeedCriteria.SYNCHRONOUS);
				boolean motorCurveEnabled = false;
				if (selectedProductLineIDSupplier != null) {
					ProductLineModel productLineModel = productLineWeb.getDetailsBySupplierID(selectedProductLineIDSupplier, userPreferences);
					if (productLineModel != null) {
						motorCurveEnabled = productLineModel.isMotorCurvesEnabled();
					}
				}

				String selectedSpeed = request.getParameter("SelectedSpeed");
				if(selectedSpeed != null && selectedSpeed.length() > 0 && !selectedSpeed.equals("-")) {
					try {
						if (motorCurveEnabled) {
							oc.setSpeedUser(OperatingConditions.SPEED_USER_NOT_CHECKED);
						} else {
							oc.setSpeedUser(Double.parseDouble(selectedSpeed));
						}
					} catch(NumberFormatException e) {
						e.printStackTrace();
					}
					oc.setDiaSetItemUser(OperatingConditions.INVALID_DIAMETER);
				}
			}
		}

		String selectedCurveNumber = request.getParameter("CurveNumber");
		if(selectedCurveNumber != null && selectedCurveNumber.length() > 0 && !selectedCurveNumber.equals("-")) {
			oc.setCurveNumberSetItemSystem(selectedCurveNumber);
		}

		String savedFlag = request.getParameter("IsSavedFlag");
		if(savedFlag != null && savedFlag.length() > 0) {
			userPreferences.setSaved(stringToBoolean(savedFlag));
		}

		String sortColumn = request.getParameter("SortColumn");
		if(sortColumn != null && sortColumn.length() > 0) {
			//System.out.println("***** SortColumn param = " + sortColumn);
			PumpDetailsSortCriteria criteria = userPreferences.getSortCriteria();
			criteria.setCriteria1(sortColumn);
		}

		String sortOrder = request.getParameter("SortOrder");
		if(sortOrder != null && sortOrder.length() > 0) {
			//System.out.println("***** SortOrder param = " + sortOrder);
			PumpDetailsSortCriteria criteria = userPreferences.getSortCriteria();
			criteria.setSort1(Integer.parseInt(sortOrder));
		}

		String hideNearMissesPerfDS = request.getParameter("HideNearMisses");
		if(hideNearMissesPerfDS != null && hideNearMissesPerfDS.length() > 0) {
			userPreferences.setHideNearMissesPerfDS(stringToBoolean(hideNearMissesPerfDS));
		}
		// Set detailsPage
		oc.setDetailsPage(OperatingConditions.PUMP_DETAILS_FROM_SEARCH_RESULTS);
	}

	/**
	 * helper method for processSearchResults()
	 * @param oc
	 * @param pumpID
	 * @param stages
	 * @param setNumber
	 */
	private void setCompatiblePumpInOC(OperatingConditions oc, String pumpID, String stages, String dia, int setNumber) {
		PumpSetConditions pump = new PumpSetConditionsImpl();
		pump.setPumpID(Integer.parseInt(pumpID));
		pump.setStageCount(Integer.parseInt(stages));
		pump.setStagesSetItemUserSet(true);
		try {
			double diaVal = Double.parseDouble(dia);
			if(diaVal>0) {
				pump.setSvRated(diaVal);
				pump.setDiaSetItemUserSet(true);
			}
		} catch(Exception e) {
		}
		pump.setEnabled(true);
		oc.setPumpSetConditions(pump,setNumber);
	}

	/** performs the processing for the ThumbnailCurves page*/
	void processThumbnailCurves() {
		OperatingConditions oc = userPreferences.getOperatingConditions();

		String temp = "";

		//check for a popup window request
		temp = request.getParameter("DisplayCustomUOMWindow");
		if(temp != null && temp.equals("true")) {
			targetPage += "&displayCustomUOMWindow=true";
			userSettings.setDirty(true); //force a putUserSettings

		}

		//session.setAttribute("thumbnailsPageReference", targetPage.substring(targetPage.indexOf("?page=")+6).trim());
		String thumbnailPage = request.getParameter("ThumbnailPage");
		if (thumbnailPage != null && thumbnailPage.length() > 0) {
			thumbnailPageParam = thumbnailPage;

			// append ThumbnailPage parameter
			targetPage += "&ThumbnailPage=" + thumbnailPageParam;
		}

		String selectionExistsFlag = request.getParameter("SelectionExistsFlag");
		if(selectionExistsFlag != null && selectionExistsFlag.length() > 0) {
			userPreferences.setSelectionExists(stringToBoolean(selectionExistsFlag));
		}

		String selectedProductLineIDSupplier = request.getParameter("SelectedProductLineIDSupplier");
		if(selectedProductLineIDSupplier != null && selectedProductLineIDSupplier.length() > 0) {
			userPreferences.setSelectedProductLineIDSupplier(selectedProductLineIDSupplier);
		}

		String selectedPumpIDSupplier = request.getParameter("SelectedPumpIDSupplier");
		if(selectedPumpIDSupplier != null && selectedPumpIDSupplier.length() > 0) {
			userPreferences.setSelectedPumpIDSupplier( selectedPumpIDSupplier );

			userPreferences.resetOperatingConditionsForSearchResults();

			setMixedStageInfo(oc);
		}

		String gearSelected = request.getParameter("SelectedGear");
		if(gearSelected != null && gearSelected.length() > 0) {
			oc.setGearSelected( gearSelected );
		}

		String vaneSelected = request.getParameter("SelectedVane");
		if(vaneSelected != null && vaneSelected.length() > 0) {
			oc.setVaneSelectedFromSearchPage( vaneSelected );
		}

		String selectedStages = request.getParameter("StagesDisplay");
		if(selectedStages != null && selectedStages.length() > 0) {
			oc.setValue(OperatingConditions.STAGES_USER, selectedStages);
		}

		String isVariableSpeedStr = request.getParameter("VariableSpeed");
		boolean isVariableSpeed = false;
		if(isVariableSpeedStr != null && isVariableSpeedStr.length() > 0) {
			isVariableSpeed = Boolean.valueOf(isVariableSpeedStr).booleanValue();
		}
		if(isVariableSpeed) {
			oc.setSpeedCriteria(SpeedCriteria.VARIABLE);

			String selectedDiameter = request.getParameter("SelectedDiameter");
			if(selectedDiameter != null && selectedDiameter.length() > 0) {
				oc.setSpeedUser(OperatingConditions.SPEED_USER_NOT_CHECKED);
				try {
					oc.setDiaSetItemUser(Double.parseDouble(selectedDiameter));
				} catch (NumberFormatException e) {
					e.printStackTrace();
				}
			}
		} else {
			oc.setSpeedCriteria(SpeedCriteria.SYNCHRONOUS);

			String selectedSpeed = request.getParameter("SpeedRated");
			if(selectedSpeed != null && selectedSpeed.length() > 0) {
				try {
					oc.setSpeedUser(Double.parseDouble(selectedSpeed));
				} catch (NumberFormatException e) {
					e.printStackTrace();
				}
				oc.setDiaSetItemUser(OperatingConditions.INVALID_DIAMETER);
			}
		}

		String selectedCurveNumber = request.getParameter("CurveNumber");
		if(selectedCurveNumber != null && selectedCurveNumber.length() > 0 && !selectedCurveNumber.equals("-")) {
			oc.setCurveNumberSetItemSystem(selectedCurveNumber);
		}

		String savedFlag = request.getParameter("IsSavedFlag");
		if(savedFlag != null && savedFlag.length() > 0) {
			userPreferences.setSaved(stringToBoolean(savedFlag));
		}
	}

	/**
	 * performs the processing for the PerformanceDatasheet page
	 */
	void processPerformanceDatasheet() {
		ParameterMap parameters = new ParameterMap(request);
		OperatingConditions oc = userPreferences.getOperatingConditions();
		String temp = "";

		do {  //not a loop, just a way to escape this code block once a popup has been found

			//see if this is a print request
			temp = request.getParameter("performanceCurvePrintRequest");
			if(temp != null && temp.equals("true")) {
				//append displayPDF parameter
				targetPage += "&displayPDF=true";
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayCustomUOMWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayCustomUOMWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayDownloadItemXMLWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&downloadItemXML=true";
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayLiquidPropertiesWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayLiquidPropertiesWindow=true";
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayNPSHAvailableWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayNPSHAvailableWindow=true";
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayDriverRatingWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayDriverRatingWindow=true";
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DownloadPdfXML");
			if(temp != null && temp.equals("true")) {
				targetPage += "&downloadPdfXML=true";
				break;
			}

		} while(false);  //not a loop, just a way to escape this code block once a popup has been found


		//twistie status
		OrgSetup orgSetup = userPreferences.getOrgSetup();
		if(orgSetup != null) {
			temp = request.getParameter("headerInfoDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.perfDatasheet_HEADERINFO_displayStyle, temp);
			}

			temp = request.getParameter("performanceCurveDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.perfDatasheet_PERFORMANCECURVE_displayStyle, temp);
			}

			temp = request.getParameter("performanceDetailsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.perfDatasheet_PERFORMANCEDETAILS_displayStyle, temp);
			}

			temp = request.getParameter("performanceOptionsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.perfDatasheet_PERFORMANCEOPTIONS_displayStyle, temp);
			}

			// set mixedStagePerformanceDisplayStyle
			temp = request.getParameter("mixedStagePerformanceDisplayStyle");
			if (temp != null) {
				orgSetup.setValue(OrgSetup.perfDatasheet_MIXEDSTAGEPERFORMANCE_displayStyle, temp);
			}

			//set minimizeTrimmedStagesDisplayStyle here
			temp = request.getParameter("minimizeTrimmedStagesDisplayStyle");
			if (temp != null) {
				orgSetup.setValue(OrgSetup.perfDatasheet_MINIMIZETRIMMEDSTAGES_displayStyle, temp);
			}

			//flow#2 persistence, userPreferences will also set it in the org setup
			temp = request.getParameter("flow2DisplayStyle");
			if(temp != null) {
				userPreferences.setFlowSecondaryEnabled(temp);
			}

			//alertSection persistence
			temp = request.getParameter("alertSectionDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.perfDatasheet_ALERTSECTION_displayStyle, temp);
			}
		}

		readHeaderInfo();


		/*
		 * data values
		 */

		/*if(request.getParameter("LanguageID") != null) {
			languageID = Integer.parseInt(request.getParameter("LanguageID"));
			userSettings.setLanguageID(languageID);
		}*/
		temp = request.getParameter(PumpDetails.FLOW_RATED + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.FLOW_RATED, request.getParameter(PumpDetails.FLOW_RATED));
		}

		temp = request.getParameter(PumpDetails.FLOW_SECONDARY + "Dirty");
		if((temp != null) && (temp.equals("true"))) {

			//see if the flow secondary needs to be auto populated, or if it was simply edited by the user
			temp = request.getParameter(PumpDetails.FLOW_SECONDARY + "AutoPopulate");
			String secondaryFlowValue = null;
			if((temp != null) && (temp.equals("true")) && (orgSetup!=null)) {
				//need to autopopulate
				temp = orgSetup.getValue(OrgSetup.FLOW2_autoPopulateMultiplier);
				if(temp != null) {
					secondaryFlowValue = String.valueOf(Double.parseDouble(oc.getValue(PumpDetails.FLOW_RATED)) * Double.parseDouble(temp));
				}
			} else {
				//flow2 was edited by the user
				secondaryFlowValue = request.getParameter(PumpDetails.FLOW_SECONDARY);
			}

			//set flow2 in the operating conditions
			if(secondaryFlowValue != null) {
				oc.setValue(OperatingConditions.FLOW_SECONDARY, secondaryFlowValue);
			}
		}

		/**
		 * HEAD_RATED, VISCOSITY_RATED, and NPSH_AVAILABLE must be read and set
		 * in the operatingConditions after the
		 * readFluidDensityRatedAndUpdateRelatedMeasureGroups() method.
		 *
		 */
		readFluidDensityRatedAndUpdateRelatedMeasureGroups(oc);

		temp = request.getParameter(PumpDetails.SG_MAX + "Dirty");
		if ((temp != null) && (temp.equals("true"))) {
			String densityMax = request.getParameter(PumpDetails.SG_MAX);
			if (oc.getUserSettings().getDoubleValue(densityMax) > 0.0) {
				oc.setValue(OperatingConditions.SG_MAX, densityMax);
			}
		}

		temp = request.getParameter(PumpDetails.HEAD_RATED + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.HEAD_RATED, request.getParameter(PumpDetails.HEAD_RATED));
		}

		temp = request.getParameter(PumpDetails.PRESSURE_MAX_SUCTION + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.PRESSURE_MAX_SUCTION, request.getParameter(PumpDetails.PRESSURE_MAX_SUCTION));
		}

		temp = request.getParameter(PumpDetails.PRESSURE_SUCTION_RATED + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.PRESSURE_SUCTION_RATED, request.getParameter(PumpDetails.PRESSURE_SUCTION_RATED));
		}



		temp = request.getParameter(OperatingConditions.PRESSURE_VAPOR_RATED + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.PRESSURE_VAPOR_RATED, request.getParameter(OperatingConditions.PRESSURE_VAPOR_RATED));
		}

		String stagesUserCheck = request.getParameter("StagesSetItemUser");
		if(stagesUserCheck != null && stagesUserCheck.toLowerCase().equals("on")) {
			oc.setValue(OperatingConditions.STAGES_USER, request.getParameter(PumpDetails.STAGES_DISPLAY));
		} else {
			oc.setValue(OperatingConditions.STAGES_USER, "0");
		}

		//minimize trimmed stages
		String mtsSet =  null;
		String mtsValue = null;
		for (int i=1; i<= Wrapper.MINIMIZE_TRIMS_STAGE_SETS; i++){
			mtsSet = request.getParameter("mtsSet_" + String.valueOf(i));
			mtsValue = request.getParameter("mtsValue_" + String.valueOf(i));
			if (mtsSet != null && mtsValue != null){
				oc.setUserMinimizeTrimStages(i-1, Integer.parseInt(mtsValue));
			} else {
				oc.setUserMinimizeTrimStages(i-1, -1);  //set to undefined
			}
		}

		temp = request.getParameter("driverRatingCheckboxDirty");
		if(temp != null && temp.equals("true")) {
			String driverRatingCheckbox = request.getParameter("driverRatingCheckbox");
			if(driverRatingCheckbox != null && driverRatingCheckbox.toLowerCase().equals("on")) {
				temp = request.getParameter("motorRating");
				if(temp != null) {
					oc.setValue(OperatingConditions.DRIVER_RATING_USER, temp);
				}
			} else {
				oc.setValue(OperatingConditions.DRIVER_RATING_USER, "0");
			}
		}

		// set default speed for multi-speed curves in OperatingConditions
		temp = request.getParameter(PumpDetails.SPEED_RATED);
		if(temp != null) {
			oc.setMultiSpeedCurvesDefaultSpeed((int)this.userSettings.getDoubleValue(temp));
		}

		String diaUserCheck = request.getParameter("DiaSetItemUser");
		if(diaUserCheck != null && diaUserCheck.toLowerCase().equals("on")) {
			//compute correct parameter name
			String diaRated;
			switch(userPreferences.getSelectedPumpDetails().getSolveVariant()) {
				default:
				case SolveVariant.IMPELLER_DIAMETER:
					diaRated = request.getParameter(PumpDetails.IMPELLER_DIAMETER_RATED);
					//save dia if not null
					if(diaRated != null) {
						oc.setSolveVariantDiameter(Double.parseDouble(diaRated));
					}
					break;
				case SolveVariant.SPEED:
					diaRated = request.getParameter(PumpDetails.IMPELLER_SPEED_RATED);
					//save dia if not null
					if(diaRated != null) {
						oc.setValue(OperatingConditions.IMPELLER_SPEED_RATED, diaRated);
					}
					break;
				case SolveVariant.IMPELLER_WIDTH:
					diaRated = request.getParameter(PumpDetails.IMPELLER_WIDTH_RATED);
					//save dia if not null
					if(diaRated != null) {
						oc.setSolveVariantWidth(Double.parseDouble(diaRated));
					}
					break;
				case SolveVariant.PROPELLER_PITCH:
					diaRated = request.getParameter(PumpDetails.PROPELLER_PITCH_RATED);
					//save dia if not null
					if(diaRated != null) {
						oc.setSolveVariantPitch(Double.parseDouble(diaRated));
					}
					break;
				case SolveVariant.AIR_PRESSURE:
					diaRated = request.getParameter(PumpDetails.AIR_PRESSURE_RATED);
					//save dia if not null
					if(diaRated != null) {
						oc.setValue(OperatingConditions.AIR_PRESSURE_RATED, diaRated);
					}
					break;
			}
		} else {
			oc.setDiaSetItemUser(OperatingConditions.INVALID_DIAMETER);
		}

		// set SpeedCriteriaItemUser
		String speedCriteriaItemUser = request.getParameter("SpeedCriteriaItemUser");
		if (speedCriteriaItemUser != null && speedCriteriaItemUser.length() > 0) {
			if (speedCriteriaItemUser.equals("Synchronous")) {
				oc.setSpeedCriteria(SpeedCriteria.SYNCHRONOUS);
			} else {
				// speedCriteriaItemUser = "Variable"
				oc.setSpeedCriteria(SpeedCriteria.VARIABLE);
			}
		}
		//DEBUG
		//System.out.println("NavigationFlags.java: oc.getSpeedCriteria() = " + oc.getSpeedCriteria());


		// get Service Factor, Use Service Factor parameters
		temp = request.getParameter(PumpDetails.SERVICE_FACTOR+"Dirty");
		if(temp != null && temp.equals("true")) {
			temp = request.getParameter(PumpDetails.SERVICE_FACTOR);
			if(temp != null) {
				try {
					oc.setServiceFactorUser(Double.parseDouble(temp));
				}
				catch (NumberFormatException ex) {
					ex.printStackTrace();
				}
			}
		}
		temp = request.getParameter(PumpDetails.USE_SERVICE_FACTOR+"Dirty");
		if(temp != null && temp.equals("true")) {
			temp = request.getParameter(PumpDetails.USE_SERVICE_FACTOR);
			if(temp != null) {
				oc.setValue(PumpDetails.USE_SERVICE_FACTOR, "on");
			} else {
				oc.setValue(PumpDetails.USE_SERVICE_FACTOR, "false");
			}
		}

		// set in Operating Conditions whether or not Mixed Stage Performance is enabled
		String isMixedStagePerformanceEnabled = request.getParameter("isMixedStagePerformanceEnabled");

		// loop through set #'s for Mixed Stage Performance selections
		if(isMixedStagePerformanceEnabled!=null && isMixedStagePerformanceEnabled.equals("true")) {
			for (int i=2; i<=5; i++) {
				// initialize pump to be passed to Operating Conditions
				PumpSetConditions pump = new PumpSetConditionsImpl();

				String pumpIDSelected = request.getParameter("pumpSetItemUserSet" + String.valueOf(i));
				if (pumpIDSelected != null && pumpIDSelected.length() > 0 && !pumpIDSelected.equalsIgnoreCase("none")) {
					// set pump ID
					pump.setPumpID(Integer.parseInt(pumpIDSelected));
					//DEBUG
					//System.out.println("NavigationFlags.java: pump for set #" + i + " set with pumpID = " + Integer.parseInt(pumpIDSelected));

					String stagesSelected = request.getParameter("stagesSetItemUserSet" + String.valueOf(i));
					if (stagesSelected != null && stagesSelected.length() > 0) {
						// set stages
						pump.setStageCount(Integer.parseInt(stagesSelected));
						pump.setStagesSetItemUserSet(true);
						//DEBUG
						//System.out.println("NavigationFlags.java: pump for set #" + i + " set with " + Integer.parseInt(stagesSelected) + " stages");
					}

					String svSelected = request.getParameter("svRatedSetItemUserSet" + String.valueOf(i));
					if (svSelected != null && svSelected.length() > 0) {
						// set solveVariant, value will be passed in using system UOM
						if (i==5) {
							String asfRatedDiaSet5 = request.getParameter("asfRatedDiaSet5");
							if ("on".equals(asfRatedDiaSet5)) {
								pump.setSvRated(Double.parseDouble(svSelected));
								pump.setDiaSetItemUserSet(true);
							}
						} else {
							pump.setSvRated(Double.parseDouble(svSelected));
							pump.setDiaSetItemUserSet(true);
						}
						//DEBUG
						//System.out.println("NavigationFlags.java: pump for set #" + i + " set with " + Double.parseDouble(svSelected) + " solveVariant");
					}

					String enabled = request.getParameter("pumpSetItemUserSet" + String.valueOf(i) + "Enabled");
					if (enabled != null) {
						// set stages
						pump.setEnabled(true);
						//DEBUG
						//System.out.println("NavigationFlags.java: pump for set #" + i + " set to enabled");
					} else if (i == 5 && request.getParameter("pumpSetItemUserSet5FixedAFS") != null) {
						pump.setEnabled(true);
					} else {
						pump.setEnabled(false);
						//DEBUG
						//System.out.println("NavigationFlags.java: pump for set #" + i + " set to disabled");
					}
				} else {
					pump = null;
					//DEBUG
					//System.out.println("NavigationFlags.java: pump for set #" + i + " is null");
				}

				oc.setPumpSetConditions(pump, i);
			}
		}

		/*
		//DEBUG
		// check all pumps
		for (int i=2; i<=5; i++) {
			if (i <= 4) {
				CompatiblePumpSelected pump = oc.getSelectedCompatiblePump(i);
				if (pump == null) {
					System.out.println("retrieved pump for set " + i + " is null");
				} else {
					System.out.println("retrieved pump for set " + i + " is not null...");
					System.out.println("- pumpID = " + pump.getPumpID());
					System.out.println("- stages = " + pump.getStageCount());
					System.out.println("- enabled = " + pump.isEnabled());
				}
			} else {
				CompatiblePumpSelected pump = oc.getSelectedCompatiblePumpAlternateFirstStage();
				if (pump == null) {
					System.out.println("retrieved pump for set " + i + " is null");
				} else {
					System.out.println("retrieved pump for set " + i + " is not null...");
					System.out.println("- pumpID = " + pump.getPumpID());
					System.out.println("- stages = " + pump.getStageCount());
					System.out.println("- enabled = " + pump.isEnabled());
				}
			}
		}
		*/

		temp = request.getParameter(PumpDetails.NPSH_AVAILABLE + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.NPSH_AVAILABLE, request.getParameter(PumpDetails.NPSH_AVAILABLE));
		}

		temp = request.getParameter(PumpDetails.LIQUID_DESCRIPTION + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.LIQUID_DESCRIPTION, request.getParameter(PumpDetails.LIQUID_DESCRIPTION));
		}

		temp = request.getParameter(PumpDetails.LIQUID_TYPE + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.LIQUID_TYPE, request.getParameter(PumpDetails.LIQUID_TYPE));
		}

		temp = request.getParameter(PumpDetails.SOLIDS_DIAMETER_MAX + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.SOLIDS_DIAMETER_MAX, request.getParameter(PumpDetails.SOLIDS_DIAMETER_MAX));
		}

		if (HttpParamUtils.getBooleanParamSafely(parameters, Attributes.SOLIDS_CONCENTRATION_BY_VOLUME + "Dirty") == true) {
			oc.setValue(Attributes.SOLIDS_CONCENTRATION_BY_VOLUME, request.getParameter(Attributes.SOLIDS_CONCENTRATION_BY_VOLUME));
		}

		temp = request.getParameter(PumpDetails.TEMPERATURE_MAX + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.TEMPERATURE_MAX, request.getParameter(PumpDetails.TEMPERATURE_MAX));
		}

		String vratedDirty = request.getParameter(PumpDetails.VISCOSITY_RATED+"Dirty");
		if (vratedDirty != null && vratedDirty.equals("true")) {
			String viscosityRated = request.getParameter(PumpDetails.VISCOSITY_RATED);
			if (oc.getUserSettings().getDoubleValue(viscosityRated) > 0.0) {
				oc.setValue(OperatingConditions.VISCOSITY_RATED, viscosityRated);
			}
		}

		temp = request.getParameter(PumpDetails.FREQUENCY + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.FREQUENCY, request.getParameter(PumpDetails.FREQUENCY));
		}

		temp = request.getParameter(PumpDetails.DRIVER_SIZING_SPEC + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			if(userPreferences.getSelectedPumpDetails().isSubcategoryDisabled(SubcategoryConstants.DRIVER_SIZE)) {
				oc.setValue(OperatingConditions.DRIVER_SIZING_SPEC, request.getParameter(PumpDetails.DRIVER_SIZING_SPEC));
			} else {
				String productLineIDSupplier = userPreferences.getSelectedProductLineIDSupplier();
				oc.getProductOptionsUser().setPerformanceOptionRequested(productLineIDSupplier, SubcategoryConstants.DRIVER_SIZE, request.getParameter(PumpDetails.DRIVER_SIZING_SPEC));
			}
		}

		temp = request.getParameter(PumpDetails.DRIVER_MARGIN_OVER_SPEC + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.MARGIN_OVER_SPEC, request.getParameter(PumpDetails.DRIVER_MARGIN_OVER_SPEC));
		}

		// Viscosity Correction Spec
		temp = request.getParameter(OperatingConditions.VISCOSITY_CORRECTION_SPEC);
		if(temp != null) {
			oc.setValue(OperatingConditions.VISCOSITY_CORRECTION_SPEC, temp);
		}

		String productLineIDSupplier = userPreferences.getSelectedProductLineIDSupplier();
		String mocID = request.getParameter(PumpDetails.MATERIAL_REQUESTED);
		if(mocID != null) {
			oc.setMaterialOfConstructionRequested(productLineIDSupplier, mocID);
		}

		String isPDPumpString = request.getParameter("isPDPump");
		boolean isPDPump = Boolean.valueOf(isPDPumpString).booleanValue();
		boolean isGearPODirty = false;
		String selectedGearPO_1 = null;
		if(isPDPump) {
			//get original SC-Gear PO
			selectedGearPO_1 = oc.getProductOptionsUser().getPerformanceOptionRequested(productLineIDSupplier, SubcategoryConstants.GEAR);
			if(selectedGearPO_1 == null) {
				//get first PO in the list, should be PO-AUTO
				List poList = userPreferences.getSelectedPumpDetails().getSelectorPerformanceOptionList().getSelectorPerformanceOptionList(SubcategoryConstants.GEAR);
				if(poList != null) {
					selectedGearPO_1 = ((SelectorPerformanceOption)poList.iterator().next()).getCode();
				} else {
					selectedGearPO_1 = AutoUpgradeOption.AUTO_UPGRADE_CODE;
				}
			}
		}
		// process product line options
		ProductLineModel productLineModel = productLineWeb.getDetailsBySupplierID(productLineIDSupplier, userPreferences);
		if(productLineModel != null) {
			processProductLinePerformanceOptions(oc, productLineModel);
		}

		if(isPDPump) {
	//		get SC-Gear PO after processing them
			String selectedGearPO_2 = oc.getProductOptionsUser().getPerformanceOptionRequested(productLineIDSupplier, SubcategoryConstants.GEAR);
			//if
			isGearPODirty = !selectedGearPO_1.equals(selectedGearPO_2);
		}

		String speedUserCheck = request.getParameter("SpeedSetItemUser");
		if(speedUserCheck != null && speedUserCheck.toLowerCase().equals("on") && (!isPDPump || (isPDPump && !isGearPODirty))) {
			oc.setValue(OperatingConditions.SPEED_USER, request.getParameter(PumpDetails.SPEED_RATED));
		} else {
			oc.setValue(OperatingConditions.SPEED_USER, String.valueOf(OperatingConditions.SPEED_USER_NOT_CHECKED));
		}

		String sizeListTypeRecalc = request.getParameter("sizeListTypeRecalc");
		if(sizeListTypeRecalc != null && sizeListTypeRecalc.length() > 0 && sizeListTypeRecalc.equals("true") && (!isPDPump || (isPDPump && !isGearPODirty))) {
			//set size list mode (detailsPage flag is set to BEP Recalc)
			if(isPDPump){
				userPreferences.resetOperatingConditionsForPDSizeList();
			} else {
				userPreferences.resetOperatingConditionsForSizeList(false);
			}
			oc.setDetailsPage(OperatingConditions.PUMP_DETAILS_REGENERATION_BEP_RECALC);
			userPreferences.setPumpDetailsRecalcNeeded(true);
		}

		oc.getHideNearMissOnPdf().readHttpParameters(parameters, ScreenNames.PERFORMANCE_DATASHEET_SCREEN);

		/* removed for IDD#3830: For PD pumps, overriding the speed (and click on Cancel) doesn't stick
		else {
			String isPDPump = request.getParameter("isPDPump");
			if(isPDPump != null && isPDPump.equals("true")){
				oc.setSpeedUser(0);
			}
		}*/

		String searchResultsDirtyFlag = request.getParameter("SearchResultsDirtyFlag");
		if(searchResultsDirtyFlag != null && searchResultsDirtyFlag.length() > 0) {
			userPreferences.setSearchResultsRecalcNeeded(stringToBoolean(searchResultsDirtyFlag));
		}

		String savedFlag = request.getParameter("IsSavedFlag");
		if(savedFlag != null && savedFlag.length() > 0) {
			userPreferences.setSaved(stringToBoolean(savedFlag));
		}

		String catalogTrimsOnly = request.getParameter(PumpDetails.CATALOG_TRIMS_ONLY);
		if (catalogTrimsOnly != null) {
			oc.setCatalogTrimsOnly(true);
		} else {
			oc.setCatalogTrimsOnly(false);
		}
		oc.setCatalogTrimsOnlyUserSet(true);

		// yAxisCurveSettings
		PageSettingsCollection yAxisPageSettingsCollection = userPreferences.getChartAxisGridControls().getYAxisPageSettingsCollection();
		yAxisPageSettingsCollection.readHttpParameters(parameters, SelectorChartType.DATASHEET, userSettings);

		String recalcMode = request.getParameter("recalcMode");
		if(Boolean.parseBoolean(recalcMode)) {
			userPreferences.setPumpDetailsRecalcNeeded(true);
		}
	}



	/**
	 * This method will read the fluidDensity value submit by the user and update {@link OperatingConditions}.
	 * The measure groups that are affected by a change in fluidDensity will be updated, using the old density value and this newly submitted density.
	 * These measure groups are updated using the previously selected unit of measures (because the old values are stored internally in this unit). <br /><br />
	 *
	 * <b>DO NOT READ the value or unit of measure for HEAD_RATED, VISCOSITY_RATED, and NPSH_AVAILABLE
	 * before this method.</b>
	 *
	 * Since this method will adjust the current HEAD_RATED, VISCOSITY_RATED, and NPSH_AVAILABLE
	 * in the operatingConditions, those values MUST be read and set after this method.<br />
	 *
	 * @param oc
	 * @see #adjustAllMeasureGroupsUsingDensity(OperatingConditions, double, double)
	 */
	private void readFluidDensityRatedAndUpdateRelatedMeasureGroups(OperatingConditions oc) {
		// retrieve user input for fluid density rated
		if ("true".equals(request.getParameter(OperatingConditions.FLUID_DENSITY + "Dirty"))) {
			double oldDensity = oc.getFluidDensity();
			boolean updateFluidDensity = updateFluidDensity(oc);
			if (updateFluidDensity) {
				double newDensity = oc.getFluidDensity();
				FluidDensityAdjustment fluidDensityAdjustment = new FluidDensityAdjustment(oc, new UnitOfMeasureFacade(oc.getUserSettings(), oc), oldDensity, newDensity);
				fluidDensityAdjustment.adjustAllMeasureGroups();
			}
		}
	}

	/**
	 * Update the {@link OperatingConditions} with the submitted fluidDensity and its unit of measure
	 * @param oc
	 */
	private boolean updateFluidDensity(OperatingConditions oc) {
		//read the unit of measure
		String fluidDensityUnitString = request.getParameter(OperatingConditions.FLUID_DENSITY + "Unit");
		int fdUomID;

		if (fluidDensityUnitString != null && fluidDensityUnitString.length() > 0) {
			fdUomID = Integer.parseInt(fluidDensityUnitString);
		} else {
			// page is not submitting uom for fluidDensity
			fdUomID = oc.getUserSettings().getSelectedUnitOfMeasure(OperatingConditions.FLUID_DENSITY).getID();
		}

		// read the value
		String densityRated = request.getParameter(OperatingConditions.FLUID_DENSITY);
		// update
		if (oc.getUserSettings().getDoubleValue(densityRated) > 0.0) {
			oc.setValue(OperatingConditions.FLUID_DENSITY, densityRated, fdUomID);
		} else {
			return false;
		}
		return true;
	}

	/**
	 * Performs the processing for the Life Cycle Cost page.
	 */
	void processLifeCycleCost() {

		do {  //not a loop, just a way to escape this code block once a popup has been found

			// determine if PDF print request
			String temp = request.getParameter("lifeCycleCostPrintRequest");
			if(temp != null && temp.equals("true")) {
				//append displayPDF parameter
				targetPage += "&displayPDF=true";
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayCustomUOMWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayCustomUOMWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

		}while(false); //not a loop, just a way to escape this code block once a popup has been found

		// get org setup
		OrgSetup orgSetup = userPreferences.getOrgSetup();

		// retrieve twistie status
		String loadProfilesDisplayStyle = request.getParameter("loadProfilesDisplayStyle");
		if (loadProfilesDisplayStyle != null) {
			orgSetup.setValue(OrgSetup.lifeCycleCost_LOADPROFILES_displayStyle, loadProfilesDisplayStyle);
		}
		String additionalLCCDisplayStyle = request.getParameter("additionalLCCDisplayStyle");
		if (additionalLCCDisplayStyle != null) {
			orgSetup.setValue(OrgSetup.lifeCycleCost_ADDITIONALLCC_displayStyle, additionalLCCDisplayStyle);
		}

		// get operating conditions
		OperatingConditions oc = userPreferences.getOperatingConditions();

		// get life cycle cost
		LifeCycleCost lcc = oc.getLifeCycleCost();

		if (lcc == null) {
			// create new life cycle cost if not yet created
			lcc = new LifeCycleCost(oc.getFluidDensity());
			lcc.initializeLoadProfiles(oc.getFlowReqd(), 5);
			lcc.setUserSettings(oc.getUserSettings());
		}

		if(lcc.getUserSettings() == null) {
			lcc.setUserSettings(oc.getUserSettings());
		}

		// retrieve life cycle cost settings
		String pumpLife = request.getParameter("lifeExpectedPump");
		String flowSetting = request.getParameter("flowCriteriaLCC");
		String speedSetting = request.getParameter("speedCriteriaLCC");

		String operationSetting = request.getParameter("timeCriteriaLCC");
		if (operationSetting !=  null && operationSetting.length() > 0) {
			if (operationSetting.equals("percentOfYear")) {
				lcc.setTimeCriteriaLCC(LifeCycleCost.PERCENT);
			} else {
				lcc.setTimeCriteriaLCC(LifeCycleCost.REGULAR_UNIT);
			}
		}
		// set life cycle cost settings
		if (pumpLife != null && pumpLife.length() > 0) {
			lcc.setLifeExpectedPump(lcc.getUserSettings().getDoubleValue(pumpLife));
		}

		/**
		 * IDD#08973: when user hits the lifecycleCost page, always set the searchResults to be dirty to force the searches to be
		 * run again.
		 */
		userPreferences.setSearchResultsRecalcNeeded(true);


		int size = lcc.getLoadProfiles().size();
		for (int i = 1; i <= size; i++) {
			int currentIndex = i -1;
			LifeCycleCostLoadProfile profile = lcc.getLoadProfiles().get(currentIndex);
			profile.setUserSettings(lcc.getUserSettings());


			if (flowSetting !=  null && flowSetting.length() > 0) {
				if (flowSetting.equals("percent")) {
					profile.setFlowCriteriaLCC(LifeCycleCostLoadProfile.PERCENT);
				} else {
					profile.setFlowCriteriaLCC(LifeCycleCostLoadProfile.REGULAR_UNIT);
				}
			}

			if (speedSetting !=  null && speedSetting.length() > 0) {
				if (speedSetting.equals("Variable")) {
					profile.setVariableSpeed(true);
				} else {
					profile.setVariableSpeed(false);
				}
			}

			if (operationSetting !=  null && operationSetting.length() > 0) {
				if (operationSetting.equals("percentOfYear")) {
					profile.setTimeCriteriaLCC(LifeCycleCostLoadProfile.PERCENT);
				} else {
					profile.setTimeCriteriaLCC(LifeCycleCostLoadProfile.REGULAR_UNIT);
				}
			}

			// set profile values
			String flowLoadProfileDirty = request.getParameter("flowLoadProfile" + i + "Dirty");
			if (flowLoadProfileDirty != null && flowLoadProfileDirty.length() > 0) {
				String flow = request.getParameter("flowLoadProfile" + i);
				if (flow != null && flow.length() > 0) {
					profile.setValue(LifeCycleCostLoadProfile.FLOW_USER, flow);
					if(profile.getFlowUser() == 0) {
						lcc.getLoadProfiles().set(currentIndex, new LifeCycleCostLoadProfile(0, lcc.getLifeExpectedPump(), lcc.getFluidDensity()));
					}
				}
			}
			String timeLoadProfileDirty = request.getParameter("timeLoadProfile" + i + "Dirty");
			if(timeLoadProfileDirty != null && timeLoadProfileDirty.length() > 0) {
				String time = request.getParameter("timeLoadProfile" + i);
				if (time != null && time.length() > 0) {
					profile.setValue(LifeCycleCostLoadProfile.TIME_USER, time);
				}
			}

			String energyCost = request.getParameter("energyCostLoadProfile" + i);
			if (energyCost != null && energyCost.length() > 0) {
				// IDD#6690 changed to currency
				profile.setValue(LifeCycleCostLoadProfile.ENERGY_COST, energyCost);
			}
			String enabled = request.getParameter("loadProfile" + i + "Enabled");
			if (enabled != null && enabled.length() > 0) {
				profile.setEnabledAndResetCalculatedValues(true);
			} else {
				profile.setEnabledAndResetCalculatedValues(false);
			}
			String etaMotor = request.getParameter("etaMotorLoadProfile" + i);
			if (etaMotor != null && etaMotor.length() > 0) {
				profile.setValue(LifeCycleCostLoadProfile.MOTOR_EFFICIENCY, etaMotor);
			}
			String etaDrive = request.getParameter("etaDriveLoadProfile" + i);
			if (etaDrive != null && etaDrive.length() > 0) {
				profile.setValue(LifeCycleCostLoadProfile.DRIVE_EFFICIENCY, etaDrive);
			}
			String systemCurve = request.getParameter("systemCurveLoadProfile" + i);
			if (systemCurve != null && systemCurve.length() > 0) {
				profile.setSystemCurveNumber(Integer.parseInt(systemCurve));
			}
		}

		// retrieve additional life cycle costs
		String routineMaintenanceCost = request.getParameter("costLCCAnnualMaintenance");
		if (routineMaintenanceCost != null && routineMaintenanceCost.length() > 0) {
			lcc.setValue(LifeCycleCost.COST_LCC_ANNUAL_MAINTENANCE, routineMaintenanceCost);
		}
		String repairCost = request.getParameter("costLCCAnnualRepair");
		if (repairCost != null && repairCost.length() > 0) {
			lcc.setValue(LifeCycleCost.COST_LCC_ANNUAL_REPAIR, repairCost);
		}
		String operatingCost = request.getParameter("costLCCAnnualOperating");
		if (operatingCost != null && operatingCost.length() > 0) {
			lcc.setValue(LifeCycleCost.COST_LCC_ANNUAL_OPERATING, operatingCost);
		}
		String downtimeCost = request.getParameter("costLCCAnnualDowntime");
		if (downtimeCost != null && downtimeCost.length() > 0) {
			lcc.setValue(LifeCycleCost.COST_LCC_ANNUAL_DOWNTIME, downtimeCost);
		}
		String otherAnnualCosts = request.getParameter("costLCCAnnualOther");
		if (otherAnnualCosts != null && otherAnnualCosts.length() > 0) {
			lcc.setValue(LifeCycleCost.COST_LCC_ANNUAL_OTHER, otherAnnualCosts);
		}
		String initialInvestmentCost = request.getParameter("costLCCOnceInitial");
		if (initialInvestmentCost != null && initialInvestmentCost.length() > 0) {
			lcc.setValue(LifeCycleCost.COST_LCC_ONCE_INITIAL, initialInvestmentCost);
		}
		String installationAndCommissioningCost = request.getParameter("costLCCOnceInstall");
		if (installationAndCommissioningCost != null && installationAndCommissioningCost.length() > 0) {
			lcc.setValue(LifeCycleCost.COST_LCC_ONCE_INSTALL, installationAndCommissioningCost);
		}
		String decommissioningCost = request.getParameter("costLCCOnceDecom");
		if (decommissioningCost != null && decommissioningCost.length() > 0) {
			lcc.setValue(LifeCycleCost.COST_LCC_ONCE_DECOM, decommissioningCost);
		}
		String environmentalCost = request.getParameter("costLCCAnnualEnv");
		if (environmentalCost != null && environmentalCost.length() > 0) {
			lcc.setValue(LifeCycleCost.COST_LCC_ANNUAL_ENV, environmentalCost);
		}
		String otherOneTimeCostsStart = request.getParameter("costLCCOnceYearZeroOther");
		if (otherOneTimeCostsStart != null && otherOneTimeCostsStart.length() > 0) {
			lcc.setValue(LifeCycleCost.COST_LCC_ONCE_YEAR_ZERO_OTHER, otherOneTimeCostsStart);
		}

		String otherOneTimeCostsEnd = request.getParameter("costLCCOnceYearLifeOther");
		if (otherOneTimeCostsEnd != null && otherOneTimeCostsEnd.length() > 0) {
			lcc.setValue(LifeCycleCostLoadProfile.COST_LCC_ONCE_YEAR_LIFE_OTHER, otherOneTimeCostsEnd);
		}

		// retrieve interest rate, inflation rate, total net present LCC
		String interestRate = request.getParameter("rateLCCInterest");
		if (interestRate != null && interestRate.length() > 0) {
			lcc.setValue(LifeCycleCost.RATE_LCC_INTEREST, interestRate);
		}
		String inflationRate = request.getParameter("rateLCCInflation");
		if (inflationRate != null && inflationRate.length() > 0) {
			lcc.setValue(LifeCycleCost.RATE_LCC_INFLATION, inflationRate);
		}

		// show that speeds are from LCC page if required
		String setSpeeds = request.getParameter("SetMultiSpeedFromLCC");
		if (setSpeeds != null && setSpeeds.equals("true")) {
			dao.setMultiSpeedFromLCC("true");
		}

		// set life cycle costs on operating conditions
		oc.setLifeCycleCost(lcc);
	}

	// performs the processing for the MultiSpeedCurves page
	void processMultiSpeedCurves() {
		OperatingConditions oc = userPreferences.getOperatingConditions();

		do { //not a loop, just a way to escape this code block once a popup has been found

			// determine if PDF print request
			String temp = request.getParameter("multiSpeedCurvesPrintRequest");
			if(temp != null && temp.equals("true")) {
				//append displayPDF parameter
				temp = request.getParameter("multiSpeedCurvesPrintType");
				if(temp!=null && temp.equals("4")) {
					targetPage += "&displayPDF=portrait";
					break;
				} else {
					targetPage += "&displayPDF=landscape";
					break;
				}

			}

			//check for a popup window request
			temp = request.getParameter("DisplayCustomUOMWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayCustomUOMWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

		} while(false); //not a loop, just a way to escape this code block once a popup has been found

		// retrieve twistie status
		OrgSetup orgSetup = userPreferences.getOrgSetup();
		if(orgSetup != null) {
			String curveDataDisplayStyle = request.getParameter("curveDataDisplayStyle");
			if (curveDataDisplayStyle != null) {
				orgSetup.setValue(OrgSetup.multiSpeedCurves_CURVEDATA_displayStyle, curveDataDisplayStyle);
			}
			String performanceDisplayStyle = request.getParameter("performanceDisplayStyle");
			if (performanceDisplayStyle != null) {
				orgSetup.setValue(OrgSetup.multiSpeedCurves_PERFORMANCE_displayStyle, performanceDisplayStyle);
			}
			String curveDisplayStyle = request.getParameter("curveDisplayStyle");
			if (curveDisplayStyle != null) {
				orgSetup.setValue(OrgSetup.multiSpeedCurves_CURVE_displayStyle, curveDisplayStyle);
			}
		}

		// reset selected multispeed curves
		oc.resetMultiSpeedCurvesSelected();

		ParameterMap parameters = new ParameterMap(request);
		oc.getHideNearMissOnPdf().readHttpParameters(parameters, ScreenNames.MULTI_SPEED_CURVES_SCREEN);

		// add user-defined multispeed curves
		for (int i = 1; i <= 6; i++) {
			MultiSpeedCurveSelected multiSpeedCurve = new MultiSpeedCurveSelected(oc);
			multiSpeedCurve.setUserSettings(userPreferences.getUserSettings());

			String speedMode = request.getParameter("speedMode");
			if (speedMode != null && !speedMode.equals("")) {
				if (speedMode.equals("Input")) {
					multiSpeedCurve.setGenerationType(MultiSpeedCurveSelected.SPEED_INPUT);
				} else if (speedMode.equals("Calculated")) {
					multiSpeedCurve.setGenerationType(MultiSpeedCurveSelected.SPEED_CALCULATED);
				}
			}

			String speed = request.getParameter("speedMultiSpeed" + i);
			if (speed != null && !speed.equals("")) {
				try {
					multiSpeedCurve.setSpeed(Integer.parseInt(speed));
				} catch (NumberFormatException e) {
					e.printStackTrace();
				}
			}

			String flow = request.getParameter("flowMultiSpeed" + i);
			if (flow != null && !flow.equals("")) {
				multiSpeedCurve.setValue(MultiSpeedCurveSelected.FLOW_RATED, flow);
			}

			String head = request.getParameter("headMultiSpeed" + i);
			if (head != null && !flow.equals("")) {
				multiSpeedCurve.setValue(MultiSpeedCurveSelected.HEAD_RATED, head);
			}

			String headCurveDisplayed = request.getParameter("headCurveMultiSpeed" + i + "Enabled");
			if (headCurveDisplayed != null) {
				multiSpeedCurve.setHeadCurveDisplayed(true);
				// Temporarily key flowRate curve off same info
				multiSpeedCurve.setFlowRateCurveDisplayed(true);
			} else {
				multiSpeedCurve.setHeadCurveDisplayed(false);
//				 Temporarily key flowRate curve off same info
				multiSpeedCurve.setFlowRateCurveDisplayed(false);
			}

			String etaCurveDisplayed = request.getParameter("etaCurveMultiSpeed" + i + "Enabled");
			if (etaCurveDisplayed != null) {
				multiSpeedCurve.setEtaCurveDisplayed(true);
			} else {
				multiSpeedCurve.setEtaCurveDisplayed(false);
			}

			String powerCurveDisplayed = request.getParameter("powerCurveMultiSpeed" + i + "Enabled");
			if (powerCurveDisplayed != null) {
				multiSpeedCurve.setPowerCurveDisplayed(true);
			} else {
				multiSpeedCurve.setPowerCurveDisplayed(false);
			}

			String npshCurveDisplayed = request.getParameter("npshCurveMultiSpeed" + i + "Enabled");
			if (npshCurveDisplayed != null) {
				multiSpeedCurve.setNPSHCurveDisplayed(true);
			} else {
				multiSpeedCurve.setNPSHCurveDisplayed(false);
			}

			String lineStyle = request.getParameter("lineStyleMultiSpeed" + i);
			String lineColor = request.getParameter("lineColorMultiSpeed" + i);
			String lineWeight = request.getParameter("lineWeightMultiSpeed" + i);
			if (lineStyle != null && lineColor != null && lineWeight != null) {
				CurveStyle style = new CurveStyle(Integer.parseInt(lineStyle), CurvePreferences.getColorFromRGBString(lineColor), Integer.parseInt(lineWeight));
				multiSpeedCurve.setCurveStyle(style);
			}

			String enabled = request.getParameter("displayCurveMultiSpeed" + i + "Enabled");
			if (enabled != null) {
				multiSpeedCurve.setEnabled(true);
			} else {
				multiSpeedCurve.setEnabled(false);
			}

			// add multi-speed curve to selected list
			oc.addMultiSpeedCurveSelected(multiSpeedCurve);
		}

		// yAxisCurveSettings
		PageSettingsCollection yAxisPageSettingsCollection = userPreferences.getChartAxisGridControls().getYAxisPageSettingsCollection();
		yAxisPageSettingsCollection.readHttpParameters(parameters, SelectorChartType.MULTISPEED, userSettings);

	}

	/**
	 * performs the processing for the PerformanceCurve page
	 */
	void processPerformanceCurve() {
		OperatingConditions oc = userPreferences.getOperatingConditions();
		String temp="";

		do {  //not a loop, just a way to escape this code block once a popup has been found


			// determine if PDF print request
			temp = request.getParameter("performanceCurvePrintRequest");
			if(temp != null && temp.equals("true")) {
				//append displayPDF parameter
				temp = request.getParameter("performanceCurvePrintType");
				if(temp!=null && temp.equals("2")) {
					targetPage += "&displayPDF=portrait";
					break;
				} else {
					targetPage += "&displayPDF=landscape";
					break;
				}
			}

			//check for a popup window request
			temp = request.getParameter("DisplayCustomUOMWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayCustomUOMWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

		} while(false); //not a loop, just a way to escape this code block once a popup has been found

		readHeaderInfo();

		if(request.getParameter(PumpDetails.FLOW_RATED + "Dirty").equals("true")) {
			oc.setValue(OperatingConditions.FLOW_RATED, request.getParameter(PumpDetails.FLOW_RATED));
		}

		/**
		 * HEAD_RATED, VISCOSITY_RATED, and NPSH_AVAILABLE must be read and set
		 * in the operatingConditions after the
		 * readFluidDensityRatedAndUpdateRelatedMeasureGroups() method.
		 *
		 */
		readFluidDensityRatedAndUpdateRelatedMeasureGroups(oc);


		if(request.getParameter(PumpDetails.HEAD_RATED + "Dirty").equals("true")) {
			oc.setValue(OperatingConditions.HEAD_RATED, request.getParameter(PumpDetails.HEAD_RATED));
		}

		if (request.getParameter(PumpDetails.SG_MAX + "Dirty").equals("true")) {
			String densityMax = request.getParameter(PumpDetails.SG_MAX);
			if (oc.getUserSettings().getDoubleValue(densityMax) > 0.0) {
				oc.setValue(OperatingConditions.SG_MAX, densityMax);
			}
		}

		if (request.getParameter(PumpDetails.VISCOSITY_RATED + "Dirty").equals("true")) {
			String viscosityRated = request.getParameter(PumpDetails.VISCOSITY_RATED);
			if (oc.getUserSettings().getDoubleValue(viscosityRated) > 0.0) {
				oc.setValue(OperatingConditions.VISCOSITY_RATED, viscosityRated);
			}
		}

		String searchResultsDirtyFlag = request.getParameter("SearchResultsDirtyFlag");
		if(searchResultsDirtyFlag != null && searchResultsDirtyFlag.length() > 0) {
			userPreferences.setSearchResultsRecalcNeeded(stringToBoolean(searchResultsDirtyFlag));
		}

		String savedFlag = request.getParameter("IsSavedFlag");
		if(savedFlag != null && savedFlag.length() > 0) {
			userPreferences.setSaved(stringToBoolean(savedFlag));
		}

		// yAxisCurveSettings
		PageSettingsCollection yAxisPageSettingsCollection = userPreferences.getChartAxisGridControls().getYAxisPageSettingsCollection();
		yAxisPageSettingsCollection.readHttpParameters(new ParameterMap(request), SelectorChartType.DATASHEET, userSettings);

		String recalcMode = request.getParameter("recalcMode");
		if(recalcMode != null) {
			userPreferences.setPumpDetailsRecalcNeeded(Boolean.valueOf(recalcMode).booleanValue());
		}


		//alertSection persistence
		temp = request.getParameter("alertSectionDisplayStyle");
		if(temp != null) {
			OrgSetup orgSetup = userPreferences.getOrgSetup();
			orgSetup.setValue(OrgSetup.perfCurve_ALERTSECTION_displayStyle, temp);
		}
	}

	private void readHeaderInfo() {
		OperatingConditions oc = userPreferences.getOperatingConditions();

		/* header info */
		String temp = request.getParameter(Attributes.CUSTOMER_NAME);
		if( temp != null) {
			userPreferences.getQuoteXml().setCustomerName(temp);
		}
		temp = request.getParameter(Attributes.CUSTOMER_REF);
		if( temp != null) {
			userPreferences.getQuoteXml().setCustomerReference(temp);
		}
		temp = request.getParameter(Attributes.QUOTE_NUMBER);
		if(temp != null) {
			userPreferences.getQuoteXml().setQuoteNumber(temp);
		}
		temp = request.getParameter(Attributes.ITEM_NUMBER);
		if(temp != null) {
			oc.setValue(Attributes.ITEM_NUMBER, temp);
		}
		temp = request.getParameter(Attributes.SERVICE);
		if(temp != null) {
			oc.setValue(Attributes.SERVICE, temp);
		}
		temp = request.getParameter(Attributes.QUANTITY_OF_PUMPS);
		if(temp != null) {
			oc.setValue(Attributes.QUANTITY_OF_PUMPS, temp);
		}
		temp = request.getParameter(Attributes.INDUSTRY);
		if(temp != null) {
			oc.setValue(Attributes.INDUSTRY, temp);
		}
		temp = request.getParameter(Attributes.PRODUCT_CLASSIFICATION);
		if(temp != null) {
			oc.setValue(Attributes.PRODUCT_CLASSIFICATION, temp);
		}
		temp = request.getParameter(Attributes.ORIENTATION);
		if(temp != null) {
			oc.setValue(Attributes.ORIENTATION, temp);
		}

		processApplicationPicklist();
	}

	private void processApplicationPicklist() {
		Fld_Application_List applicationPicklist = userPreferences.getQuoteXml().getApplicationPicklist();
		String application = request.getParameter("Fld_Application");
		if(applicationPicklist != null && StringUtils.isDefined(application) && NumberUtils.canParseInteger(application)) {
			OperatingConditions oc = userPreferences.getOperatingConditions();
			oc.setApplication(Integer.parseInt(application));

			String applicationDesc = StringUtils.replaceNull(applicationPicklist.getOptionDescById(application));
			oc.setApplicationDescription(applicationDesc);

		}
	}

	void processAdditionalDataPage() {
		String temp = "";

		do {  //not a loop, just a way to escape this code block once a popup has been found

			//see if this is a print request
			temp = request.getParameter("performanceCurvePrintRequest");
			if(temp != null && temp.equals("true")) {
				//append displayPDF parameter
				targetPage += "&displayPDF=true";
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayCustomUOMWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayCustomUOMWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

		} while(false); //not a loop, just a way to escape this code block once a popup has been found

		//twistie status
		OrgSetup orgSetup = userPreferences.getOrgSetup();
		if(orgSetup != null) {
			temp = request.getParameter("generalInfoDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.addlData_GENERALINFO_displayStyle, temp);
			}
			temp = request.getParameter("verticalDataDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.addlData_VERTICALDATA_displayStyle, temp);
			}
			temp = request.getParameter("nfpa20DataDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.addlData_NFPA20DATA_displayStyle, temp);
			}
			temp = request.getParameter("advancedDataDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.addlData_ADVANCEDDATA_displayStyle, temp);
			}
		}
	}

	void processDriverRatingPage() {
		OperatingConditions oc = userPreferences.getOperatingConditions();
		UnitOfMeasureFacade uomFacade = new UnitOfMeasureFacade(oc.getUserSettings(), oc);

		MotorDriverRatingSettings motorDriverRatingSettings = oc.getMotorDriverRatingSettings(userPreferences.getSelectedPumpDetails());
		ParameterMap parameters = new ParameterMap(request);
		// copy the newly calculated values to the OC when user does a submit. A recalc will not update the OC
		if (HttpParamUtils.getBooleanParamSafely(parameters, "recalcParentBrowser")) {
			motorDriverRatingSettings.readHttpParameters(parameters, uomFacade, userPreferences.getSelectedPumpDetails());
			motorDriverRatingSettings.copyToOperatingCondition(oc, userPreferences.getSelectedPumpDetails());
		} else {
			motorDriverRatingSettings.readHttpParameters(parameters, uomFacade, userPreferences.getSelectedPumpDetails());
		}

		// this is the target for the main browser window
		targetPage = request.getParameter("returnURL");
	}

	private boolean stringToBoolean(String valueString) {
		boolean valueBool = false;

		if(valueString != null && valueString.equalsIgnoreCase("true")) {
			valueBool = true;
		}

		return valueBool;
	}

	/**
	 * reads the system curve values from the request and set into backend.<br /><br />
	 *
	 * IMPORTANT: Before calling this method, the cos flow and head must be read and set from the user's request.
	 */
	private void doSystemCurves() {
		//system curves...
		OperatingConditions oc = this.userPreferences.getOperatingConditions();
		/*
		 * This code should be similar to CurvePreferences.readSystemCurveParameters()
		 */
		for(int curveNumber = 1; curveNumber <= 4; curveNumber++) {
			double flowValue = 0.0;
			double headValue = 0.0;
			double staticHeadValue = 0.0;
			String label = "";

			// need to get the selected unitOfMeasure everytime through loop, because if conversion is dependent on an operating condition
			// e.g. specific gravity, the conversion factor gets reset every time we do a conversion...
			UnitOfMeasure flowUOM = userPreferences.getUserSettings().getSelectedUnitOfMeasure(Measure.FLOW, userPreferences.getOperatingConditions());
			UnitOfMeasure headUOM = userPreferences.getUserSettings().getSelectedUnitOfMeasure(Measure.HEAD, userPreferences.getOperatingConditions());

			String curveType = "SystemCurve" + String.valueOf(curveNumber);
			String flow = request.getParameter("Flow" + curveType);
			String head = request.getParameter("Head" + curveType);
			boolean flowDirty = Boolean.valueOf(request.getParameter("Flow" + curveType + "Dirty")).booleanValue();
			boolean headDirty = Boolean.valueOf(request.getParameter("Head" + curveType + "Dirty")).booleanValue();

			if((flow != null) && (!flow.equals("")) && (head != null) && (!head.equals(""))) {
				if(flowDirty) {
					flowValue = userSettings.getDoubleValue(flow);
					flowValue = ((Double)flowUOM.convertToDefault(new Double(flowValue))).doubleValue();
				} else {
					String flowBackend = request.getParameter("Flow" + curveType + "Backend");
					if(flowBackend != null) {
						flowValue = Double.parseDouble(flowBackend);
					} else {
						//IDD#6860: KSB cos page cannot define the FlowSystemCurve1Backend,
						//			because it is dependent on the cos flow, which can be modified on that page.
						//			This code depends that the systemCurve flow was set when setting the cos flow.
						SystemCurve sysCurve = oc.getSystemCurve(curveNumber, false);
						if(sysCurve != null) {
							flowValue = sysCurve.getFlow();
						}
					}
				}
				if(headDirty) {
					headValue = userSettings.getDoubleValue(head);
					headValue = ((Double)headUOM.convertToDefault(new Double(headValue))).doubleValue();
				} else {
					String headBackend = request.getParameter("Head" + curveType + "Backend");
					if(headBackend != null) {
						headValue = Double.parseDouble(headBackend);
					} else {
						//IDD#6860: KSB cos page cannot define the HeadSystemCurve1Backend,
						//			because it is dependent on the cos head, which can be modified on that page
						//			This code depends that the systemCurve head was set when setting the cos head.
						SystemCurve sysCurve = oc.getSystemCurve(curveNumber, false);
						if(sysCurve != null) {
							headValue = sysCurve.getHead();
						}
					}
				}

				if(flowValue == 0) {
					flowValue = oc.getFlowReqd();
				}

				if(headValue == 0) {
					headValue = oc.getHeadReqd();
				}

				String staticHead = request.getParameter("HeadStatic" + curveType);
				if((staticHead != null) && (!staticHead.equals(""))) {
					// need to refresh the selected unitOfMeasure, because if conversion is dependent on an operating condition
					// e.g. specific gravity, the conversion factor gets reset every time we do a conversion...
					headUOM = userPreferences.getUserSettings().getSelectedUnitOfMeasure(Measure.HEAD, userPreferences.getOperatingConditions());
					staticHeadValue = userSettings.getDoubleValue(staticHead);
					staticHeadValue = ((Double)headUOM.convertToDefault(new Double(staticHeadValue))).doubleValue();
				}
				label = request.getParameter("Label" + curveType);
				boolean display = (request.getParameter("Display" + curveType) != null);
				SystemCurve systemCurve = new SystemCurve(curveNumber, staticHeadValue, flowValue, headValue);
				if(label != null) {
					systemCurve.setLabel(label);
				}
				systemCurve.setVisible(display);
				oc.setSystemCurve(systemCurve, curveNumber);
			} else {
				oc.removeSystemCurve(curveNumber);
			}
		}
	}

	private void processProductLinePerformanceOptions(OperatingConditions oc, ProductLineModel productLineModel) {
		processProductLinePerformanceOptions(oc.getProductOptionsUser(), productLineModel, new UnitOfMeasureFacade(userSettings, oc));
	}
	/**
	 * Used by the PerformanceDatasheet, COS and productLineOptions pages to process and store the performance options
	 * @param oc
	 * @param productLineModel
	 */
	private void processProductLinePerformanceOptions(ProductOptionsUser productOptionsUser, ProductLineModel productLineModel, UnitOfMeasureFacade uomFacade) {
		List categoryList = productLineModel.getCategoryList();
			Iterator catIterator = categoryList.iterator();
			while(catIterator.hasNext()) {
				SelectorCategory category = (SelectorCategory)catIterator.next();
				List subcategoryList = category.getSubcategoryList();
				Iterator iterator = subcategoryList.iterator();
				while(iterator.hasNext()) {
					SelectorSubcategory subcategory = (SelectorSubcategory)iterator.next();
					String subcategoryCode = subcategory.getCode();
					//the ProductLineOptionsPage.appendSubcategoryListXML() will replace dashes with underscores
					//because javascript's eval function fails on input field names with dashes
					//here we must use the original subcategoryCode and replace the dashes
					//(its possible the code didnt have dashes so we must always reformat the original to match the incomming parameter)
					String selectedPO = request.getParameter(replaceDashes(subcategoryCode + productLineModel.getSupplierID())); //we replace the dashes with underscores because javascript's eval function fails on input field names with dashes
					if(selectedPO != null) {
						if(subcategory.getDisplayType() == SelectorSubcategory.TEXTBOX) {
							String selectedPODirty = request.getParameter(replaceDashes(subcategoryCode + productLineModel.getSupplierID())+"Dirty"); //we replace the dashes with underscores because javascript's eval function fails on input field names with dashes
							if(selectedPODirty != null && selectedPODirty.equals("true")) {
								//This is stored as a string, but as of now we are treating the value as doubles
								productOptionsUser.setSubcategoryTextboxValueFromDisplayUom(productLineModel.getSupplierID(), subcategoryCode,  selectedPO, productLineModel.getSelectorPerformanceOptionList(), uomFacade);
							}
						} else {
							productOptionsUser.setPerformanceOptionRequested(productLineModel.getSupplierID(), subcategoryCode, selectedPO);
						}
					}
				}
			}
	}

	void processAdvSortPage() {
		PumpDetailsSortCriteria sortCriteria = userPreferences.getSortCriteria();

		//set the criteria (the pull downs)
		String value = request.getParameter("firstSort");
		if(value != null) {
			sortCriteria.setCriteria1(value);
		}

		value = request.getParameter("secondSort");
		if(value != null && !value.equals("")) {
			sortCriteria.setCriteria2(value);
		} else {
			//there is no 2nd sort criteria
			sortCriteria.setCriteria2(null);
		}

		value = request.getParameter("thirdSort");
		if(value != null && !value.equals("")) {
			sortCriteria.setCriteria3(value);
		} else {
			//there is no 3rd sort criteria
			sortCriteria.setCriteria3(null);
		}

		//set the sort orders
		value = request.getParameter("firstSortType");
		if(value != null) {
			try {
				sortCriteria.setSort1(Integer.parseInt(value));
			} catch(NumberFormatException nfEx) {
				nfEx.printStackTrace();
			}
		}

		value = request.getParameter("secondSortType");
		if(value != null) {
			try {
				sortCriteria.setSort2(Integer.parseInt(value));
			} catch(NumberFormatException nfEx) {
				nfEx.printStackTrace();
			}
		}

		value = request.getParameter("thirdSortType");
		if(value != null) {
			try {
				sortCriteria.setSort3(Integer.parseInt(value));
			} catch(NumberFormatException nfEx) {
				nfEx.printStackTrace();
			}
		}

		//this is the target for the main browser window
		targetPage = request.getParameter("returnURL");
	}

	void processNPSHAvailablePage() {
		OperatingConditions oc = this.userPreferences.getOperatingConditions();
		NPSHAvailableCalculator npshCalc = oc.getNPSHAvailableCalculator();

		ParameterMap parameterMap = new ParameterMap(request);
		npshCalc.readHttpParameters(parameterMap);
		npshCalc.calculateNpshAvailable();

		// copy the newly calculated values to the OC when user does a submit. A recalc will not update the OC
		if (HttpParamUtils.getBooleanParamSafely(parameterMap, "recalcParentBrowser")) {
			npshCalc.copyToOperatingConditions(oc);
		}


		//this is the target for the main browser window
		targetPage = request.getParameter("returnURL");
	}

	void processLiquidPropertiesPage() {
		OperatingConditions operatingConditions = userPreferences.getOperatingConditions();

		LiquidPropertiesPageSettings liquidPropertiesPageSettings = operatingConditions.getLiquidPropertiesPageSettings();
		liquidPropertiesPageSettings.readHttpParameters(new ParameterMap(request), userPreferences);

		String searchResultsDirtyFlag = request.getParameter("SearchResultsDirtyFlag");
		if (StringUtils.isDefined(searchResultsDirtyFlag)) {
			userPreferences.setSearchResultsRecalcNeeded(Boolean.valueOf(searchResultsDirtyFlag));
		}

		// copy the newly calculated values to the OC when user does a submit. A recalc will not update the OC
		if (HttpParamUtils.getBooleanParamSafely(new ParameterMap(request), "recalcParentBrowser")) {
			liquidPropertiesPageSettings.copyLiquidPropertiesSettingsToOCAndApplyAdjustments(operatingConditions);
			// clear out temp settings
			operatingConditions.clearLiquidPropertiesPageSettings();
		}

		// this is the target for the main browser window
		targetPage = request.getParameter("returnURL");
	}

	void processMultipleConditionsCOS() {
		new MultipleConditionsSubmitReader(userPreferences, request).readHtmlParameters();

		// this is the target for the main browser window
		targetPage = request.getParameter("returnURL");
	}

	void processITOConditonsOfServicePage() {
		do {
			//check for a popup window request
			String temp = request.getParameter("DisplayCustomUOMWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayCustomUOMWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

		} while(false); //not a loop, just a way to escape this code block once a popup has been found


		OperatingConditions operatingConditions = userPreferences.getOperatingConditions();

		if (request.getParameter("flowRatedTakeoff1Dirty").equals("true")) {
			String value = request.getParameter("flowRatedTakeoff1");
			if (value != null) {
				operatingConditions.setValue(OperatingConditions.FLOW_RATED_TAKEOFF1, value);
			}
		}

		if (request.getParameter("headRatedTakeoff1Dirty").equals("true")) {
			String value = request.getParameter("headRatedTakeoff1");
			if (value != null) {
				operatingConditions.setValue(OperatingConditions.HEAD_RATED_TAKEOFF1, value);
			}
		}

		//checkbox parameter
		operatingConditions.setValue(OperatingConditions.ENABLED_TAKEOFF1, request.getParameter("enabledTakeoff1"));

		if (request.getParameter("flowRatedTakeoff2Dirty").equals("true")) {
			String value = request.getParameter("flowRatedTakeoff2");
			if (value != null) {
				operatingConditions.setValue(OperatingConditions.FLOW_RATED_TAKEOFF2, value);
			}
		}

		if (request.getParameter("headRatedTakeoff2Dirty").equals("true")) {
			String value = request.getParameter("headRatedTakeoff2");
			if (value != null) {
				operatingConditions.setValue(OperatingConditions.HEAD_RATED_TAKEOFF2, value);
			}
		}

		//checkbox parameter
		operatingConditions.setValue(OperatingConditions.ENABLED_TAKEOFF2, request.getParameter("enabledTakeoff2"));

		if(checkForITOCosError3(operatingConditions,alert)) {
			String targetConditionsOfService = targetPath + ScreenNames.CONDITIONS_OF_SERVICE_URL;
			this.targetPage = targetConditionsOfService;
		}
	}

	void processITODatasheetPage() {
		String temp = "";

		do {  //not a loop, just a way to escape this code block once a popup has been found

			//see if this is a print request
			temp = request.getParameter("itoDatasheetPrintRequest");
			if(temp != null && temp.equals("true")) {
				//append displayPDF parameter
				targetPage += "&displayPDF=true";
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayCustomUOMWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayCustomUOMWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

		} while(false); //not a loop, just a way to escape this code block once a popup has been found

		//twistie status
		OrgSetup orgSetup = userPreferences.getOrgSetup();
		if(orgSetup != null) {
			temp = request.getParameter("perfDetailsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(orgSetup.itoDatasheet_PERFDETAILS_displayStyle, temp);
			}
			temp = request.getParameter("perfCurveDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(orgSetup.itoDatasheet_PERFCURVE_displayStyle, temp);
			}
		}


		OperatingConditions operatingConditions = userPreferences.getOperatingConditions();

		//Hide near miss on pdf option
		ParameterMap parameters = new ParameterMap(request);
		operatingConditions.getHideNearMissOnPdf().readHttpParameters(parameters, ScreenNames.DATASHEET_ITO_SCREEN);

		/*
		 * Set the flow and head takeoff values on the Operating Conditions
		 */
		String param = request.getParameter("flowRatedTakeoff1Dirty");
		if(param != null && param.equals("true")) {
			operatingConditions.setValue(OperatingConditions.FLOW_RATED_TAKEOFF1, request.getParameter("flowRatedTakeoff1"));
		}
		param = request.getParameter("headRatedTakeoff1Dirty");
		if(param != null && param.equals("true")) {
			operatingConditions.setValue(OperatingConditions.HEAD_RATED_TAKEOFF1, request.getParameter("headRatedTakeoff1"));
		}
		param = request.getParameter("flowRatedTakeoff2Dirty");
		if(param != null && param.equals("true")) {
			operatingConditions.setValue(OperatingConditions.FLOW_RATED_TAKEOFF2, request.getParameter("flowRatedTakeoff2"));
		}
		param = request.getParameter("headRatedTakeoff2Dirty");
		if(param != null && param.equals("true")) {
			operatingConditions.setValue(OperatingConditions.HEAD_RATED_TAKEOFF2, request.getParameter("headRatedTakeoff2"));
		}
		param = request.getParameter("flowRatedTakeoffFinalDischargeDirty");
		if(param != null && param.equals("true")) {
			operatingConditions.setValue(OperatingConditions.FLOW_RATED, request.getParameter("flowRatedTakeoffFinalDischarge"));
		}
		param = request.getParameter("headRatedTakeoffFinalDischargeDirty");
		if(param != null && param.equals("true")) {
			operatingConditions.setValue(OperatingConditions.HEAD_RATED, request.getParameter("headRatedTakeoffFinalDischarge"));
		}

		//checkbox parameter
		//operatingConditions.setValue(OperatingConditions.ENABLED_TAKEOFF2, request.getParameter("enabledTakeoff2"));

		/*
		 * Set the diameter and stages on the CompatiblePumpSelected objects
		 */

//		get compatible pump from pumpDetails
		CompatiblePumpSelected[] pumpList = this.userPreferences.getSelectedPumpDetails().getSystemSelectedCompatiblePumps();
		//boolean compatiblePumpEnabled[] = new boolean[5];
		for (int i=1; i<=5; i++) {
			// initialize pump to be passed to Operating Conditions
			PumpSetConditions pump = null;

			CompatiblePumpSelected compatiblePump = pumpList[i-1];
			if(compatiblePump != null) {
				pump = new PumpSetConditionsImpl(compatiblePump);

				String stagesDisplaySet = request.getParameter("stagesSetItemUserSet" + String.valueOf(i));
				if(stagesDisplaySet != null) {
					pump.setStagesSetItemUserSet(true);

					String stagesSelected = request.getParameter("stagesDisplaySet" + String.valueOf(i));
					if (stagesSelected != null && stagesSelected.length() > 0) {
						// set stages
						try {
							pump.setStageCount(Integer.parseInt(stagesSelected));
						} catch(Exception e) {
							e.printStackTrace();
						}
						//DEBUG
						//System.out.println("NavigationFlags.java: pump for set #" + i + " set with " + Integer.parseInt(stagesSelected) + " stages");
					}
				} else {
					pump.setStagesSetItemUserSet(false);
				}

				String svDisplaySet = request.getParameter("diaSetItemUserSet" + String.valueOf(i));
				if(svDisplaySet != null) {
					pump.setDiaSetItemUserSet(true);

					String diaSelected = request.getParameter("svDisplaySet" + String.valueOf(i));
					if (diaSelected != null && diaSelected.length() > 0) {
						// set stages
						try {
							pump.setSvRated(Double.parseDouble(diaSelected));
						} catch(Exception e) {
							e.printStackTrace();
						}
						//DEBUG
						//System.out.println("NavigationFlags.java: pump for set #" + i + " set with " + Integer.parseInt(stagesSelected) + " stages");
					}
				} else {
					pump.setDiaSetItemUserSet(false);
				}

				/*String enabled = request.getParameter("pumpSetItemUserSet" + String.valueOf(i) + "Enabled");
				if (enabled != null) {
					compatiblePumpEnabled[i-1] = true;
					pump.setEnabled(true);
					//DEBUG
					//System.out.println("NavigationFlags.java: pump for set #" + i + " set to enabled");
				} else {
					compatiblePumpEnabled[i-1] = false;
					pump.setEnabled(false);
					//DEBUG
					//System.out.println("NavigationFlags.java: pump for set #" + i + " set to disabled");
				}*/
			}

			operatingConditions.setPumpSetConditions(pump, i);
		}

		/*if(!compatiblePumpEnabled[0] && !compatiblePumpEnabled[4]) {
			operatingConditions.setEnabledTakeoff1(false);
		}

		if(!compatiblePumpEnabled[1]) {
			operatingConditions.setEnabledTakeoff2(false);
		}*/

		// yAxisCurveSettings
		PageSettingsCollection yAxisPageSettingsCollection = userPreferences.getChartAxisGridControls().getYAxisPageSettingsCollection();
		yAxisPageSettingsCollection.readHttpParameters(parameters, SelectorChartType.DATASHEET, userSettings);

		String searchResultsDirtyFlag = request.getParameter("SearchResultsDirtyFlag");
		if(searchResultsDirtyFlag != null && searchResultsDirtyFlag.length() > 0) {
			userPreferences.setSearchResultsRecalcNeeded(stringToBoolean(searchResultsDirtyFlag));
		}

		String recalcMode = request.getParameter("recalcMode");
		if(recalcMode != null) {
			userPreferences.setPumpDetailsRecalcNeeded(Boolean.valueOf(recalcMode).booleanValue());
		}

	}

	void processMotorPerformanceDatasheetPage() {
		String temp = "";

		do {  //not a loop, just a way to escape this code block once a popup has been found

			//see if this is a print request
			temp = request.getParameter("motorPerformanceDatasheetPrintRequest");
			if(temp != null && temp.equals("true")) {
				//append displayPDF parameter
				targetPage += "&displayPDF=true";
				break;
			}

			//check for a popup window request
			temp = request.getParameter("DisplayCustomUOMWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayCustomUOMWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

		} while(false); //not a loop, just a way to escape this code block once a popup has been found


		OperatingConditions operatingConditions = userPreferences.getOperatingConditions();

		/*
		 * Set the ratedVoltage
		 */
		String param = request.getParameter("ratedVoltage");
		if (param != null){
			operatingConditions.setValue(OperatingConditions.VOLTS_MTR, param);
		}

		String searchResultsDirtyFlag = request.getParameter("SearchResultsDirtyFlag");
		if(searchResultsDirtyFlag != null && searchResultsDirtyFlag.length() > 0) {
			userPreferences.setSearchResultsRecalcNeeded(stringToBoolean(searchResultsDirtyFlag));
		}

		String recalcMode = request.getParameter("recalcMode");
		if(recalcMode != null) {
			userPreferences.setPumpDetailsRecalcNeeded(Boolean.valueOf(recalcMode).booleanValue());
		}
	}

	void processMultipleConditionsDatasheet() {
		String temp = null;
		OperatingConditions oc = userPreferences.getOperatingConditions();

		/*
		 * popup window request checks
		 */
		// check for an old style popup window request
		do {  //not a loop, just a way to escape this code block once a popup has been found
			temp = request.getParameter("multipleConditionsDatasheetPrintRequest");
			if(temp != null && temp.equals("true")) {
				//append displayPDF parameter
				targetPage += "&displayPDF=true";
				break;
			}

		} while(false); //not a loop, just a way to escape this code block once a popup has been found

		//twistie status
		OrgSetup orgSetup = userPreferences.getOrgSetup();
		if(orgSetup!=null) {
			temp = request.getParameter("conditionsSectionDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.multiConditions_CONDITIONS_displayStyle, temp);
			}

			temp = request.getParameter("performanceCurveSectionDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.multiConditions_PERFCURVE_displayStyle, temp);
			}
		}

		//	check for a new style popup window request
		processPopupRequest();

		//Hide near miss on pdf option
		ParameterMap parameters = new ParameterMap(request);
		oc.getHideNearMissOnPdf().readHttpParameters(parameters, ScreenNames.MULTIPLE_CONDITIONS_DATASHEET_SCREEN);

		new MultipleConditionsSubmitReader(userPreferences, request).readHtmlParameters();

		// yAxisCurveSettings
		PageSettingsCollection yAxisPageSettingsCollection = userPreferences.getChartAxisGridControls().getYAxisPageSettingsCollection();
		yAxisPageSettingsCollection.readHttpParameters(parameters, SelectorChartType.MULTICONDITIONS, userSettings);

		int viscCorrectionSpec = HttpParamUtils.getIntParamSafely(request, "ViscosityCorrectionSpec", oc.getViscosityCorrectionSpec());
		oc.setViscosityCorrectionSpec(viscCorrectionSpec);
	}

	void processHeadLossPage() {
		OperatingConditions oc = userPreferences.getOperatingConditions();
		String temp = null;

		/*
		 * popup window request checks
		 */
//		check for an old style popup window request
		do {  //not a loop, just a way to escape this code block once a popup has been found
			temp = request.getParameter("DisplayCustomUOMWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayCustomUOMWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

			temp = request.getParameter("DisplayLiquidPropertiesWindow");
			if(temp != null && temp.equals("true")) {
				targetPage += "&displayLiquidPropertiesWindow=true";
				userSettings.setDirty(true); //force a putUserSettings
				break;
			}

			temp = request.getParameter("headLossPrintRequest");
			if(temp != null && temp.equals("true")) {
				//append displayPDF parameter
				targetPage += "&displayPDF=true";
				break;
			}
		} while(false); //not a loop, just a way to escape this code block once a popup has been found

//		check for a new style popup window request
		processPopupRequest();

		//twistie status
		OrgSetup orgSetup = userPreferences.getOrgSetup();
		if(orgSetup!=null) {
			temp = request.getParameter("headLossConditionsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.headLoss_CONDITIONS_displayStyle, temp);
			}
			temp = request.getParameter("headLossDischargeDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.headLoss_DISCHARGE_displayStyle, temp);
			}
			temp = request.getParameter("headLossSuctionDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.headLoss_SUCTION_displayStyle, temp);
			}
		}

		/*
		 * process fittings
		 */
		//read head loss parameters from the request
		int systemNumber = HttpParamUtils.getIntParamSafely(request, "systemNumber", -1);
		boolean suctionTwistieEnabled = Boolean.valueOf(request.getParameter("suctionTwistieEnabled")).booleanValue();

		if(suctionTwistieEnabled) {
			//process the suction fitting rows, if enabled
			HeadLossFittingSubmit suctionRequests = FittingSubmitFacade.processHeadLossFittingSubmit(request, FittingSection.SUCTION, systemNumber);
			oc.updateHeadLossFittings(suctionRequests);
		}

//		process the discharge fitting rows (always enabled)
		HeadLossFittingSubmit dischargeRequests = FittingSubmitFacade.processHeadLossFittingSubmit(request, FittingSection.DISCHARGE, systemNumber);
		oc.updateHeadLossFittings(dischargeRequests);


		/*
		 * process the other input fields
		 */
		HeadLoss headLoss = oc.getHeadLoss(systemNumber);

		headLoss.setNominalPipeSizeUnits(Enum.valueOf(NominalPipeSizeUnits.class, request.getParameter("nominalPipeSizeUnits")));
		headLoss.setAnyFittingsDirty(Boolean.valueOf(request.getParameter("anyFittingsDirty")));
		headLoss.getSystemType().setSelectedId(request.getParameter(SystemTypePicklist.PICKLIST_NAME));

		FrictionCalcStrategy frictionCalcStrategy = Enum.valueOf(FrictionCalcStrategy.class, request.getParameter("frictionStrategy"));
		headLoss.setFrictionCalcStrategy(frictionCalcStrategy);


		if(request.getParameter(OperatingConditions.FLOW_RATED + "Dirty").equals("true")) {
			String flowDisplay = request.getParameter(OperatingConditions.FLOW_RATED);

			if(systemNumber == 1) {
				//updating the COS will automatically update the systemCurve#1
				int flowDisplayUOM = Integer.parseInt(request.getParameter(OperatingConditions.FLOW_RATED + "Unit"));
				oc.setValue(Attributes.FLOW_RATED, flowDisplay, flowDisplayUOM);

			} else {
				//convert from display value
				UnitOfMeasureFacade uomFacade = new UnitOfMeasureFacade(userPreferences.getUserSettings(), oc);
				double flow = uomFacade.getSystemFromDisplay(flowDisplay, Measure.FLOW, oc.getFlowReqd());

				//update the system curve
				SystemCurve systemCurve = oc.getSystemCurve(systemNumber, true);
				systemCurve.setFlow(flow);

			}
		}

		temp = request.getParameter(OperatingConditions.LIQUID_DESCRIPTION);
		if(temp != null) {
			oc.setValue(OperatingConditions.LIQUID_DESCRIPTION, temp);
		}
		temp = request.getParameter(OperatingConditions.LIQUID_TYPE);
		if(temp != null) {
			oc.setValue(OperatingConditions.LIQUID_TYPE, temp);
		}

		if(request.getParameter(OperatingConditions.SOLIDS_DIAMETER_MAX + "Dirty").equals("true")) {
			oc.setValue(OperatingConditions.SOLIDS_DIAMETER_MAX, request.getParameter(OperatingConditions.SOLIDS_DIAMETER_MAX), Integer.parseInt(request.getParameter(OperatingConditions.SOLIDS_DIAMETER_MAX + "Unit")));
		}

		if(request.getParameter(OperatingConditions.TEMPERATURE_MAX + "Dirty").equals("true")) {
			oc.setValue(OperatingConditions.TEMPERATURE_MAX, request.getParameter(OperatingConditions.TEMPERATURE_MAX), Integer.parseInt(request.getParameter(OperatingConditions.TEMPERATURE_MAX + "Unit")));
		}

		/**
		 * HEAD_RATED, VISCOSITY_RATED, and NPSH_AVAILABLE must be read and set
		 * in the operatingConditions after the
		 * readFluidDensityRatedAndUpdateRelatedMeasureGroups() method.
		 *
		 */
		readFluidDensityRatedAndUpdateRelatedMeasureGroups(oc);

		// retrieve user input for fluid density max
		if (request.getParameter(OperatingConditions.SG_MAX + "Dirty").equals("true")) {
			String densityMax = request.getParameter(OperatingConditions.SG_MAX);
			if (oc.getUserSettings().getDoubleValue(densityMax) > 0.0) {
				oc.setValue(OperatingConditions.SG_MAX, densityMax, Integer.parseInt(request.getParameter(OperatingConditions.FLUID_DENSITY + "Unit")));
			}
		}

		// get engine values for fluid density rated/max
		double densityRatedEngine = oc.getFluidDensity();
		double densityMaxEngine = oc.getSGMax();

		// get density restrictions from org-setup.xml, bypass validation if values do not exist
		double densityMinAllowedUser = 0;
		double densityMaxAllowedUser = 0;
		boolean densityValidationRequired = true;
		try {
			densityMinAllowedUser = Double.parseDouble(userPreferences.getOrgSetup().getValue(OrgSetup.DENSITY_MIN_ALLOWED_USER));
			densityMaxAllowedUser = Double.parseDouble(userPreferences.getOrgSetup().getValue(OrgSetup.DENSITY_MAX_ALLOWED_USER));
		} catch (NumberFormatException e) {
			densityValidationRequired = false;
		}

		// validate that fluid density, fluid density max are within limits of organization
		if (densityValidationRequired) {
			if (densityRatedEngine < densityMinAllowedUser || densityRatedEngine > densityMaxAllowedUser ||
				densityMaxEngine < densityMinAllowedUser || densityMaxEngine > densityMaxAllowedUser) {
				// density validation failed, set in session to notify COS page
				dao.setDensityValidationFailed(true);

				// redirect back to HeadLoss page
				String headLossURL = targetPath + ScreenNames.HEAD_LOSS_URL +"&amp;useSystemNumber=" + request.getParameter("systemNumber");
				this.targetPage = headLossURL;
			} else {
				// density validation passed, set in session to notify COS page
				dao.setDensityValidationFailed(false);
			}
		}

		if (request.getParameter(OperatingConditions.VISCOSITY_RATED + "Dirty").equals("true")) {
			String viscosityRated = request.getParameter(OperatingConditions.VISCOSITY_RATED);
			if (oc.getUserSettings().getDoubleValue(viscosityRated) > 0.0) {
				oc.setValue(OperatingConditions.VISCOSITY_RATED, viscosityRated, Integer.parseInt(request.getParameter(OperatingConditions.VISCOSITY_RATED + "Unit")));
			}
		}

		temp = request.getParameter(OperatingConditions.PRESSURE_VAPOR_RATED + "Dirty");
		if((temp != null) && (temp.equals("true"))) {
			oc.setValue(OperatingConditions.PRESSURE_VAPOR_RATED, request.getParameter(OperatingConditions.PRESSURE_VAPOR_RATED), Integer.parseInt(request.getParameter(OperatingConditions.PRESSURE_VAPOR_RATED + "Unit")));
		}

		/*
		 * read inputData fields
		 * must be done after fluidDensity is set, since this impacts the uom conversions
		 */
		for(InputData inputData : headLoss.getInputData()) {
			String id = inputData.getId();
			if(Boolean.valueOf(request.getParameter("inputDataDirty_"+id))) {
				String valueParam = request.getParameter("inputData_"+id);
				if(valueParam != null) {
					double value = new UnitOfMeasureFacade(userSettings, oc).getSystemFromDisplay(valueParam, inputData.getUnitGroupId(), 0.0);
					inputData.setValue(value);
				}
			}
		}

		/*
		 *
		 * Check viscosity limits for Hazen Williams (HW)
		 * must be after frictionCalcStrategy and viscosity is set
		 */
		double viscosityRated = oc.getViscosityRated();
		if(frictionCalcStrategy == FrictionCalcStrategy.HW && (viscosityRated < 1.0 || viscosityRated > 1.13)) {
			this.alert.add(this.pageLabels.getLabel("hazenWilliamsViscosityWarning"));
		}

		/*
		 * copy must be 2nd to last
		 */
		boolean copy = Boolean.valueOf(request.getParameter("copyToSystem"));
		if(copy) {
			int copyTo = HttpParamUtils.getIntParamSafely(request, "copyToSystemNumber", -1);
			oc.copyHeadLoss(systemNumber, copyTo);
		}

		/*
		 * the solve must be last
		 */
		boolean isRecalc = Boolean.valueOf(request.getParameter("isRecalcSubmit"));
		if(!isRecalc) {
			try {
				HeadLossFacade.solve(userPreferences, headLoss);

				boolean isNavigateToSystemNumber = Boolean.valueOf(request.getParameter("isNavigateToSystemNumber"));
				if(!isNavigateToSystemNumber) {
					HeadLossFacade.updateCOSFromHeadLoss(userPreferences);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			//ensure we scroll to the same positionY
			targetPage += ("&positionY=" + request.getParameter("positionY"));
		}

		/*
		 * system curve persistence, must be done after HeadLossFacade.solve() so that the system curve has its head populated
		 */
		boolean systemCurveVisible = request.getParameter("systemCurveVisible") != null;
		SystemCurve systemCurve = oc.getSystemCurve(systemNumber, true);
		systemCurve.setVisible(systemCurveVisible);

		String systemCurveLabel = request.getParameter("systemCurveLabel");
		systemCurve.setLabel(systemCurveLabel);
	}

	void processFittingSelectionPage() {
		OperatingConditions oc = userPreferences.getOperatingConditions();

		FittingSelectionSubmit fittingSelection = FittingSubmitFacade.processFittingSelectionRequest(request);
		oc.updateFittingSelection(fittingSelection);


		//this is the target for the main browser window
		//during investigation for IDD#5830 I found that returnURL is no longer necessary
		//because the *submit.jsp will just call the javascript "recalculatePage()"
		//and that function does not require a parameter (except for some KSB pages, which are old)
		//I decided to keep this here for now, because Im not sure if its better to
		//use the returnURL directly on the parent (this is more generic)
		//or to call "recalculatePage()" on the parent (this is less code, but introduces a dependency on the javascript function)
		targetPage = request.getParameter("returnURL");
	}

	void processSpecialFittingPage() {
		OperatingConditions oc = userPreferences.getOperatingConditions();

		SpecialFittingSubmit specialFitting = FittingSubmitFacade.processSpecialFittingRequest(request);
		oc.updateSpecialFitting(specialFitting);


		//this is the target for the main browser window
		//during investigation for IDD#5830 I found that returnURL is no longer necessary
		//because the *submit.jsp will just call the javascript "recalculatePage()"
		//and that function does not require a parameter (except for some KSB pages, which are old)
		//I decided to keep this here for now, because Im not sure if its better to
		//use the returnURL directly on the parent (this is more generic)
		//or to call "recalculatePage()" on the parent (this is less code, but introduces a dependency on the javascript function)
		targetPage = request.getParameter("returnURL");
	}

	void processCurveCommentPage() {
		String curveCommentLine1 = StringUtils.removeBadCharsForXmlDisplay(request.getParameter("curveCommentLine1"));
		String curveCommentLine2 = StringUtils.removeBadCharsForXmlDisplay(request.getParameter("curveCommentLine2"));

		ChartHeader chartHeader = null;
		if(StringUtils.isDefined(curveCommentLine1)) {
			if(StringUtils.isDefined(curveCommentLine2)) {
				chartHeader = new ChartHeader(curveCommentLine1, curveCommentLine2);
			} else {
				chartHeader = new ChartHeader(curveCommentLine1);
			}
		}
		userPreferences.getOperatingConditions().setChartHeader(chartHeader);
	}

	void processCompressorCos() {
		ParameterMap parameters = new ParameterMap(request);
		GasProperties gasProperties = userPreferences.getSelectorContext().getGasProperties();

		CompressorConditionsOfService cos = userPreferences.getCompressorCOS();
		EnabledConditions enabledConditionsOriginal = cos.getConditions().getEnabledConditions();
		cos.readHttpParameters(parameters, userSettings, gasProperties);
		EnabledConditions enabledConditionsCurrent = cos.getConditions().getEnabledConditions();

		chooseSelections(false);
		Selections selections = userPreferences.getCompressorUser().getSelections();
		selections.updateCurvesDisplayedForNewlyEnabledConditions(enabledConditionsOriginal, enabledConditionsCurrent);

		String temp = "";

		//twistie status
		OrgSetup orgSetup = userPreferences.getOrgSetup();
		if(orgSetup!=null) {
			temp = request.getParameter("operatingConditionsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.compressorCos_OPERATINGCONDITIONS_displayStyle, temp);
			}
			temp = request.getParameter("headerInfoDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.compressorCos_HEADERINFO_displayStyle, temp);
			}
			temp = request.getParameter("selectionConstraintsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.compressorCos_SELECTIONCONSTRAINTS_displayStyle, temp);
			}
			temp = request.getParameter("siteConditionsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.compressorCos_SITECONDITIONS_displayStyle, temp);
			}
		}

		readHeaderInfo();

		userPreferences.setConditionsOfServiceExist(true);

		readPowerLimitsOptions(cos);
	}

	private void readPowerLimitsOptions(CompressorConditionsOfService cos) {
		String productLineSupplierID = request.getParameter("powerLimitsProductLineSupplierID");
		if(StringUtils.isDefined(productLineSupplierID)) {
			try {
				ProductLine productLine = RevisedSearchCache.getProductLine(userPreferences.getOrgID(), productLineSupplierID );
				ProductLineModel productLineModel = productLine.getDetailsForCompressor(cos);
				UnitOfMeasureFacade uomFacade = cos.getConditions().createUnitOfMeasureFacadeFromPrimary(userSettings);
				processProductLinePerformanceOptions(cos.getProductOptionsUser(), productLineModel, uomFacade);

				productLine.getDetailsForCompressor(cos);  //necessary to ensure that the product options defaults are up to date with the user's latest requested options.
			} catch (SQLException e) {
				e.printStackTrace();
			} catch (CompatibilityRuleException e) {
				e.printStackTrace();
			}
		}
	}

	/*
	 * shared methods
	 */

	private void processPopupRequest() {
		log.debug("processPopupRequest()");

		String temp = request.getParameter("DisplayPopupWindow");
		if(temp != null && temp.length() > 0) {
			if(!userPreferences.processPopupRequest(temp)) {
				alert.add("Invalid url \""+temp+"\"");
			}
		}
	}


	public String replaceDashes(String input) {
		return input.replace('-','_');
	}

	/**
	 * Checks if any ITOs are enabled along with the search criteria set to variable speed. IDD#4502
	 * Returns true if the above conditions are both true.
	 * @param oc
	 * @param alertList
	 * @return
	 */
	private boolean checkForITOCosError3(OperatingConditions oc, List alertList) {
		if(oc.isITOConditionsEnabled()) {
			if(oc.getSearchCriteria() == SearchCriteria.SPEED_VARIABLE) {
				String label = pageLabels.getLabel("itoCOSError3");
				alertList.add(label);

				return true;
			}
		}
		return false;
	}

	private void setMixedStageInfo(OperatingConditions oc) {
		/*Set mixed stage info because a pump has been chosen*/

		//first clear out the old userSelectedCompatiblePumps
		oc.clearPumpSetConditionsCollection();

		//clear out the minimizeTrimmedStages selections
		oc.clearUserMinimizeTrimStages();

		//set alternate first stage pump ID if specified
		//old code, but left in place for KSB
		String altFirstStagePumpID = request.getParameter("AlternateFirstStagePumpID");
		if (altFirstStagePumpID != null && altFirstStagePumpID.length() > 0) {
			PumpSetConditions pump = new PumpSetConditionsImpl();
			pump.setPumpID(Integer.parseInt(altFirstStagePumpID));
			pump.setEnabled(true);
			oc.setPumpSetConditions(pump, CompatiblePumpSelected.ALTERNATE_FIRST_STAGE);
		} else {
			//this should be refactored, so the above is removed and KSB uses the parameters below

			//set stage sets if specified (needed by ITO pumps)
			String pumpIDMixedStage2 = request.getParameter("pumpIDMixedStage2");
			String pumpIDMixedStage3 = request.getParameter("pumpIDMixedStage3");
			String pumpIDMixedStage4 = request.getParameter("pumpIDMixedStage4");
			String pumpIDMixedStage5 = request.getParameter("pumpIDMixedStage5");
			boolean p2Enabled = pumpIDMixedStage2 != null && pumpIDMixedStage2.length() > 0;
			boolean p3Enabled = pumpIDMixedStage3 != null && pumpIDMixedStage3.length() > 0;
			boolean p4Enabled = pumpIDMixedStage4 != null && pumpIDMixedStage4.length() > 0;
			boolean p5Enabled = pumpIDMixedStage5 != null && pumpIDMixedStage5.length() > 0;
			if(p2Enabled || p3Enabled || p4Enabled || p5Enabled) {

				boolean isMTS = Boolean.valueOf(request.getParameter("isMinimizeTrimmedStages")).booleanValue();
				if(isMTS) {
					boolean[] pumpEnabled = new boolean[] {true, p2Enabled, p3Enabled, p4Enabled, p5Enabled};
					String mtsValue = null;
					for (int i=1; i<= Wrapper.MINIMIZE_TRIMS_STAGE_SETS; i++){
						mtsValue = request.getParameter("stagesMixedStage" + String.valueOf(i));
						if (pumpEnabled[i-1] && mtsValue != null){
							oc.setUserMinimizeTrimStages(i-1, Integer.parseInt(mtsValue));
						} else {
							oc.setUserMinimizeTrimStages(i-1, -1);  //set to undefined
						}
					}

				} else {
					//if its anITO, then we must also set the first stage set
					String ito = request.getParameter("itoProductlineSelected");
					if(ito!=null && Boolean.valueOf(ito).booleanValue()) {
						//retrieve the first stage set
						String pumpIDMixedStage1 = request.getParameter("pumpIDMixedStage1");
						if(pumpIDMixedStage1 != null && pumpIDMixedStage1.length() > 0) {
							setCompatiblePumpInOC(oc, pumpIDMixedStage1, request.getParameter("stagesMixedStage1"), request.getParameter("diaMixedStage1"), 1);
						}
					}

					if(p2Enabled) {
						setCompatiblePumpInOC(oc, pumpIDMixedStage2, request.getParameter("stagesMixedStage2"), request.getParameter("diaMixedStage2"), 2);
					}
					if(p3Enabled) {
						setCompatiblePumpInOC(oc, pumpIDMixedStage3, request.getParameter("stagesMixedStage3"), request.getParameter("diaMixedStage3"), 3);
					}
					if(p4Enabled) {
						setCompatiblePumpInOC(oc, pumpIDMixedStage4, request.getParameter("stagesMixedStage4"), request.getParameter("diaMixedStage4"), 4);
					}
					if(p5Enabled) {
						setCompatiblePumpInOC(oc, pumpIDMixedStage5, request.getParameter("stagesMixedStage5"), request.getParameter("diaMixedStage5"), 5);
					}
				}
			}
		}
	}

	void processCompressorSearchPage() {
		ParameterMap parameters = new ParameterMap(request);
		CompressorMultipleConditions conditions = userPreferences.getCompressorCOS().getConditions();
		UnitOfMeasureFacade uomFacade = conditions.createUnitOfMeasureFacadeFromPrimary(userSettings);
		CurrentSearchResults currentSearchResults = userPreferences.getCompressorUser().getCurrentSearchResults();
		CurrentSearchResults.HttpStateChange state = currentSearchResults.readHttpParameters(parameters, uomFacade);

		chooseSelections(state.newSelectionChosen);

		Selections selections = userPreferences.getCompressorUser().getSelections();
		DatasheetMode datasheetMode = userPreferences.getCompressorUser().getDatasheetMode();
		if(state.newSelectionChosen && datasheetMode == DatasheetMode.primaryCos) {
			SelectedModelList selectedModelList = userPreferences.getCompressorUser().getCurrentSearchResults().getSelectedModelList();
			selections.updateCurvesDisplayedForCompareMode(selectedModelList);
		}
		if(state.datasheetModeChanged) {
			selections.updateLabelType(datasheetMode);
		}


		userPreferences.setHideNearMissesPerfDS(HttpParamUtils.getBooleanParamSafely(parameters, "HideNearMisses"));

		/*TODO - need to set the productline for whats selected, BUT if we're in compare mode it can be 2 different productlines.
		userPreferences.setSelectedProductLineIDSupplier(selection.getProductLineSupplierID());
		*/
	}

	void processCompressorDatasheetPage() {
		//twistie status
		OrgSetup orgSetup = userPreferences.getOrgSetup();
		if(orgSetup!=null) {
			String temp = request.getParameter("headerInfoDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.compressorDatasheet_HEADERINFO_displayStyle, temp);
			}
			temp = request.getParameter("operatingConditionsDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.compressorDatasheet_OPERATINGCONDITIONS_displayStyle, temp);
			}
			temp = request.getParameter("performanceDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.compressorDatasheet_PERFORMANCE_displayStyle, temp);
			}
			temp = request.getParameter("standardPerfCurveDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.compressorDatasheet_STANDARDPERFCURVE_displayStyle, temp);
			}
			temp = request.getParameter("systemPowerCurveDisplayStyle");
			if(temp != null) {
				orgSetup.setValue(OrgSetup.compressorDatasheet_SYSTEMPOWERCURVE_displayStyle, temp);
			}
			temp = request.getParameter("curveSettingsDisplayStyle");
			if(temp !=null) {
				orgSetup.setValue(OrgSetup.compressorDatasheet_CURVESETTINGS_displayStyle , temp);
			}
			temp = request.getParameter("varSpeedPowerDataDisplayStyle");
			if(temp !=null) {
				orgSetup.setValue(OrgSetup.compressorDatasheet_VARSPEEDPOWERDATA_displayStyle , temp);
			}
		}

		ParameterMap parameters = new ParameterMap(request);

		GasProperties gasProperties = userPreferences.getSelectorContext().getGasProperties();
		CompressorConditionsOfService cos = userPreferences.getCompressorCOS();
		EnabledConditions enabledConditionsOriginal = cos.getConditions().getEnabledConditions();
		cos.readHttpParameters(parameters, userSettings, gasProperties);
		EnabledConditions enabledConditionsCurrent = cos.getConditions().getEnabledConditions();

		chooseSelections(false);

		//can access the Selections only after chooseSelections()
		Selections selections = userPreferences.getCompressorUser().getSelections();
		selections.readHttpParameters(parameters, userSettings, cos.getConditions());

		//update the curves display only after selections.readHttpParameters
		selections.updateCurvesDisplayedForNewlyEnabledConditions(enabledConditionsOriginal, enabledConditionsCurrent);

		VarSpeedPowerData varSpeedPowerData = userPreferences.getCompressorCOS().getCommonData().getVarSpeedPowerData();
		Condition primaryCondition = userPreferences.getCompressorUser().getPrimaryCondition();;
		UnitOfMeasureFacade uomFacade = primaryCondition .createUnitOfMeasureFacade(userSettings);
		varSpeedPowerData.readHttpParameters(parameters, uomFacade );

		readHeaderInfo();

	}

	/**
	 * this must be called whenever there is a change in the number of user selections.
	 * For example, when results are chosen from the search results page, or conditions are copied/enabled on the datasheet or cos page.
	 */
	private void chooseSelections(boolean resetForNewSelection) {
		SelectedModelList selectedModelList = userPreferences.getCompressorUser().getCurrentSearchResults().getSelectedModelList();
		if(selectedModelList != null) {
			CompressorMultipleConditions conditions = userPreferences.getCompressorCOS().getConditions();
			Selections selections = userPreferences.getCompressorUser().getSelections();

			if(resetForNewSelection) {
				selections.resetForNewSelection();
			}

			selections.chooseSelections(selectedModelList, conditions);
		}
	}

	public void processCompressorSizeListPage() {
		ParameterMap parameters = new ParameterMap(request);
		CompressorUser compressorUser = userPreferences.getCompressorUser();
		DatasheetMode datasheetModeOriginal = userPreferences.getCompressorUser().getDatasheetMode();
		SizeListSelection selection = SizeListSelectionImpl.create(parameters, userSettings, compressorUser);

		if(selection.isValid()) {
			compressorUser.getCurrentSearchResults().selectFromSizeList(selection);
			chooseSelections(true);
			new CompressorSearchFacade(userPreferences).sizeListSelectionSearchToPopulateCos(selection);
			userPreferences.setConditionsOfServiceExist(true);

			DatasheetMode datasheetMode = userPreferences.getCompressorUser().getDatasheetMode();
			if(datasheetModeOriginal != datasheetMode) {
				Selections selections = userPreferences.getCompressorUser().getSelections();
				selections.updateLabelType(datasheetMode);
			}
		}
	}

	public void processGasConstituentsPage() {
		ParameterMap parameterMap = new ParameterMap(request);

		int conditionIndex = HttpParamUtils.getIntParamWithThrows(request, "conditionIndex");
		CompressorConditionsOfService cos = userPreferences.getCompressorCOS();
		Condition condition = cos.getCondition(conditionIndex);

		PopupRecalcPersistence popupRecalcPersistence = userPreferences.getPopupRecalcPersistence();
		GasConstituentsActual gasConstituentsTemp = popupRecalcPersistence.getGasConstituentsActual();
		FailFastHandler.assertNotNull(gasConstituentsTemp, "The GasConstituentsPage.java must store this object when creating the page.  Submit cannot be processed without this object");

		GasProperties gasProperties = userPreferences.getSelectorContext().getGasProperties();
		UnitOfMeasureFacade uomFacade = condition.createUnitOfMeasureFacade(userSettings);
		gasConstituentsTemp.readHttpParameters(parameterMap, uomFacade, gasProperties);

		boolean recalcParentBrowser = HttpParamUtils.getBooleanParamSafely(parameterMap, "recalcParentBrowser", false);
		if(recalcParentBrowser) {
			condition.setGasConstituentsActual(gasConstituentsTemp);
			popupRecalcPersistence.resetGasConstituentsActual();
			cos.runConditionsCalcs();
		} else {
			//recalc the popup
			condition.runConditionsCalcsUsingOtherGasConstituents(cos, gasConstituentsTemp);
		}
	}

	void processEmailPage( ) {
		ParameterMap parameterMap = new ParameterMap(request);
		 	String from = HttpParamUtils.getStringParam(parameterMap, "from", "");
	        String to = HttpParamUtils.getStringParam(parameterMap, "emailTo", "");
	        userPreferences.setEmailToRecipients(to);
	        String cc = HttpParamUtils.getStringParam(parameterMap, "cc", "");
	        String subject = HttpParamUtils.getStringParam(parameterMap, "subject", "");
	        String bodyText = HttpParamUtils.getStringParam(parameterMap, "body", "");
	        String filename = "PerformanceDatasheet.pdf";

	        Properties properties = new Properties();
	        properties.put("mail.smtp.host", "smtp.intelliquip.com");
	        properties.put("mail.smtp.port", "25");
	        Session mailSession = Session.getDefaultInstance(properties, null);

	        try {
	            MimeMessage message = new MimeMessage(mailSession);
	            message.setFrom(new InternetAddress(from));
	            message.setRecipients(Message.RecipientType.TO, to);
	            message.setRecipients(Message.RecipientType.CC, cc);
	            message.setSubject(subject);
	            message.setSentDate(new Date());

	            //
	            // Set the email message text.
	            //
	            MimeBodyPart messagePart = new MimeBodyPart();
	            messagePart.setText(bodyText);

	            //
	            // Set the email attachment file
	            //
	            MimeBodyPart attachmentPart = new MimeBodyPart();
	            byte[] pdfFile = generateSelectorPdf();
	            DataSource source = new ByteArrayDataSource(pdfFile, "application/pdf");
//	            FileDataSource fileDataSource = new FileDataSource(filename) {
//	                @Override
//	                public String getContentType() {
//	                    return "application/octet-stream";
//	                }
//	            };
	            attachmentPart.setDataHandler(new DataHandler(source));
	            attachmentPart.setFileName(filename);

	            Multipart multipart = new MimeMultipart();
	            multipart.addBodyPart(messagePart);
	            multipart.addBodyPart(attachmentPart);

	            message.setContent(multipart);

	            Transport.send(message);
	        } catch (MessagingException e) {
	            e.printStackTrace();
	        }
	    }

	private byte[] generateSelectorPdf() {
		List<PdfPage> pdfPages = new ArrayList<PdfPage>();
		pdfPages.add(PdfPage.PERFORMANCE_DATASHEET_PRINT);
		byte[] pdfBytes = SelectorPDF.generateSpecifiedPDFs(userPreferences, pdfPages).get(PdfPage.PERFORMANCE_DATASHEET_PRINT);
		return pdfBytes;
	}



}
